Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clarify entity fetcher contract #192

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open

Clarify entity fetcher contract #192

wants to merge 3 commits into from

Conversation

lorensr
Copy link
Contributor

@lorensr lorensr commented Nov 13, 2024

  • Should return either a single instance or null (technically can return a List with one item in it and the framework will unwrap, but not mentioning that as I wouldn't recommend it)
  • Can fetch data


In this case, we're not doing any data fetching: our `Show` instance only has an `id` field, and we implement a `Show.reviews` datafetcher in the [next section](#providing-data-with-a-data-fetcher).

However, we could instead fetch data in the entity fetcher. If our DGS served multiple fields, and they all came from the same data source, we could fetch them all at once in the entity fetcher instead of writing separate datafetchers for each field:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would leave this out from the docs - don't think we want to necessarily recommend this as a pattern.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So is it an anti-pattern to build the whole entity object? Should we always return the partial entity (only id field)?
If it is, maybe it makes sense to mentioned that it is not recommended.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO it's a valid thing to do, and sometimes the better thing to do, and many won't realize it's an option unless we say it is. Maybe can change/add language around it to say only use it in this circumstance, or "here is why you often don't want to do it?"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I guess if it's providing multiple federated fields - so would be good to highlight that.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 that this is a valid pattern

The DGS framework does most of the heavy lifting, and all we have to do is provide the following:
The Reviews DGS needs to implement an entity fetcher to handle this query.

- **Entity fetcher**: A method annotated with [`@DgsEntityFetcher`](https://javadoc.io/doc/com.netflix.graphql.dgs/graphql-dgs/latest/com/netflix/graphql/dgs/DgsEntityFetcher.html) that takes a key and returns a single instance of the entity or null.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what are the implications of returning the entity or null? which one is preferred?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it also makes sense to mention that the entity resolver must return some value for every key.


```java
@DgsEntityFetcher(name = "Show")
public Show movie(Map<String, Object> values, DataFetchingEnvironment env) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it should be CompletableFuture<Show>

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why? I don't think it needs to be?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doesn't dataLoader.load(showId) return a Future?

}
```

If there is no such Show with the given id in the database, the entity fetcher should return `null`.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

null or new Show(showId)?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe explain a bit further what this means for the federated request. E.g. will this show as an error


In this case, we're not doing any data fetching: our `Show` instance only has an `id` field, and we implement a `Show.reviews` datafetcher in the [next section](#providing-data-with-a-data-fetcher).

However, we could instead fetch data in the entity fetcher. If our DGS served multiple fields, and they all came from the same data source, we could fetch them all at once in the entity fetcher instead of writing separate datafetchers for each field:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So is it an anti-pattern to build the whole entity object? Should we always return the partial entity (only id field)?
If it is, maybe it makes sense to mentioned that it is not recommended.

@@ -173,7 +198,7 @@ public List<Review> reviews(DgsDataFetchingEnvironment dataFetchingEnvironment)

### Testing a Federated Query

You can always manually test federated queries by running the gateway and your DGS locally.
You can always manually test federated queries by running the gateway and your DGS locally.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should flip this text around and focus on testing without running a gateway, so:

  1. Write a test
  2. Test by sending a federated query directly to the DGS (e.g. using graphiql)
  3. Run your gateway locally

Copy link
Collaborator

@paulbakker paulbakker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for updating this. The changes look good, but I left some comments for further improvements.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants