github-community-projects / github-community-projects/graphql-client

Would it be possible to use Fragments just for pure re-usability? (without forced parent-child component encapsulation)

Open
#76 4 comments 1 reaction 0 assignees View on GitHub
Dominant language
Ruby
Stars
78
Forks
228
PR merge metrics
No merged PRs in 30d

Description

In regards to the [`ImplicitlyFetchedFieldError`](https://github.com/github-community-projects/graphql-client/blob/master/guides/implicitly-fetched-field-error.md), that is raised in `GraphQL::Client::Schema::ObjectType`, on `method_missing`...

- [Here is](https://github.com/github-community-projects/graphql-client/blob/a81766d7a7830f672891d8b62ad79002df4ee6d9/lib/graphql/client/schema/object_type.rb#L262) the line

```ruby
if @data.key?(field.name)
raise ImplicitlyFetchedFieldError
```

---

**Would it be possible to have the option to use fragments just for re-usability?**

For example, in the Apollo [documentation on fragments](https://www.apollographql.com/docs/react/data/fragments), it states that

Image

the main reason for fragments to exist is re-usability. It certainly emphasizes that it is specially useful when [collocating with components](https://www.apollographql.com/docs/react/data/fragments#colocating-fragments), but it does NOT say that this is the only usage that we should be able to make out of it.

In the documentation (see [collocated fragments](https://www.apollographql.com/docs/react/data/fragments#creating-colocated-fragments)), somehow states that there are two types of fragments, the ones that are "externally" (or collaterally) referred to by a component, and the ones that are defined right on that component (collated):

>A colocated fragment is just like any other fragment, except it's _defined in the same file as a particular component_ that uses the fragment's fields.
>
>After you define a fragment in a child component, the parent component can _refer to it in its own colocated fragments_, like so:

```typescript
export const FEED_ENTRY_FRAGMENT = gql`
fragment FeedEntryFragment on FeedEntry {
commentCount
repository {
full_name
html_url
owner {
avatar_url
}
}
...VoteButtonsFragment
...EntryInfoFragment
}

${VOTE_BUTTONS_FRAGMENT}
${ENTRY_INFO_FRAGMENT}
```
- In this example `VOTE_BUTTONS_FRAGMENT` and `ENTRY_INFO_FRAGMENT` are defined in (or imported from) child components.

Image

Apollo's technique to define fragments and identify if they belong to a parent or children classes can arguable, yet they offer a way.

---

Following the example of `graphlient` gem, where [**fragments** support](https://github.com/ashkan18/graphlient?tab=readme-ov-file#use-of-fragments) was added by making it aligned with `graphql-client`, in the following query...

```ruby
module Fragments
Invoice = client.parse <<~'GRAPHQL'
fragment on Invoice {
id
feeInCents
}
GRAPHQL
end

invoice_query = client.parse do
query do
invoice(id: 10) do
id
___Fragments__Invoice
end
end
end
```

... we would get the error if trying to access `feeInCents` directly from the query [`Response`](https://github.com/github-community-projects/graphql-client/blob/master/lib/graphql/client/response.rb#L9)

```ruby
response = client.execute(invoice_query)
result = response.data.invoice
result.to_h
# {"id" => 10, "feeInCents"=> 20000}
result.id
# 10
result.fee_in_cents
# raises GraphQL::Client::ImplicitlyFetchedFieldError
```

---

How would we in `graphql-client` define a fragment that belongs to the main query (or parent component)?

```ruby
invoice_query <<~'GRAPHQL'
query InvoiceById($some_id: Int) {
invoice(id: $some_id) {
id
...withFee
}
}

fragment withFee on Invoice {
id
feeInCents
}
GRAPHQL
```

provided that we can do something like this:

```ruby
response = client.execute(invoice_query)
result = response.data.invoice
result.fee_in_cents
```

without getting the error `GraphQL::Client::ImplicitlyFetchedFieldError`.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.