-
Notifications
You must be signed in to change notification settings - Fork 66
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
Docs (GraphQL): 21.03 feature documentation for federation #104
Conversation
Deploy preview for dgraph-docs-repo ready! Built with commit 12bc2f5 |
@@ -0,0 +1,129 @@ | |||
+++ | |||
title = "Apollo Federation" | |||
weight = 14 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a "description" under "title" to give us a description for SEO. Suggestion:
description = "Dgraph now supports Apollo federation so that you can create a gateway GraphQL service that includes the Dgraph GraphQL API and other GraphQL services."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for adding this!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great content! I added a few comments.
content/graphql/federation/index.md
Outdated
parent = "graphql" | ||
+++ | ||
|
||
Starting from release version 21.03 support has been added for Apollo federation. Hence making it possible to use Dgraph GraphQL API with other GraphQL services through a single gateway. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Starting from release version 21.03 support has been added for Apollo federation. Hence making it possible to use Dgraph GraphQL API with other GraphQL services through a single gateway. | |
Dgraph supports Apollo federation starting in release version 21.03. This lets you create a gateway GraphQL service that includes the Dgraph GraphQL API and other GraphQL services. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Edited to remove passive voice
content/graphql/federation/index.md
Outdated
|
||
## Support for Apollo federation directives | ||
|
||
The current implementation supports 3 directives, namely `@key`, `@extends`, and `@external`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The current implementation supports 3 directives, namely `@key`, `@extends`, and `@external`. | |
The current implementation supports the following three directives: `@key`, `@extends`, and `@external`. |
content/graphql/federation/index.md
Outdated
The current implementation supports 3 directives, namely `@key`, `@extends`, and `@external`. | ||
|
||
### `@key` directive | ||
This directive takes one field argument inside it which is called `@key` field. There are few limitations on how to use `@key` directives. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This directive takes one field argument inside it which is called `@key` field. There are few limitations on how to use `@key` directives. | |
This directive takes one field argument inside it: the `@key` field. There are few limitations on how to use `@key` directives: |
content/graphql/federation/index.md
Outdated
### `@key` directive | ||
This directive takes one field argument inside it which is called `@key` field. There are few limitations on how to use `@key` directives. | ||
|
||
User can define `@key` directive only once for a type, Support for multiple key types is not provided yet. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The items on lines 19 and 20 should be three bullets, IMO (slight suggested rewording):
- Users can define the
@key
directive only once for a type - Support for multiple key types is not currently available.
- Since the
@key
field acts as a foreign key to resolve entities from the service where it is extended, the field provided as an argument inside the@key
directive should be ofID
type or have the@id
directive on it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, good point.
content/graphql/federation/index.md
Outdated
|
||
When adding an object of type `Astronaut`, first it should be added into `AstronautService` service and then the `addAstronaut` mutation should be called with value of `id` provided as an argument which must be equal to the value in `AstronautService` service. | ||
|
||
Remember to add the `Extended Definitions` block from the generated schema of Dgraph GraphQL to the other GraphQL services schemas that are part of the gateway. This needs to be done otherwise the Apollo gateway will throw an error like `Custom directives must be implemented in every service.` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need to append Extended Definitions
now. Please remove this block.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
content/graphql/federation/index.md
Outdated
``` | ||
|
||
### `@extends` directive | ||
This directive is provided to give support for extended definitions. Suppose the above defined `User` type is defined in some service. Users can extend it to our GraphQL service by using this directive. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This directive is provided to give support for extended definitions. Suppose the above defined `User` type is defined in some service. Users can extend it to our GraphQL service by using this directive. | |
This directive is provided to give support for extended definitions. Suppose the above defined `User` type is defined in some other service. Users can extend it in Dgraph's GraphQL service by using this directive. |
We can also add that the same is also achievable with the extend
keyword, i.e., user has the choice to choose between extend type User ...
or type User @extends ...
content/graphql/federation/index.md
Outdated
This directive takes one field argument inside it: the `@key` field. There are few limitations on how to use `@key` directives: | ||
|
||
- Users can define the @key directive only once for a type | ||
- Support for multiple key types is not currently available. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Support for multiple key types is not currently available. | |
- Support for multiple key fields is not currently available. |
content/graphql/federation/index.md
Outdated
This directive is provided to give support for extended definitions. Suppose the above defined `User` type is defined in some service. Users can extend it to our GraphQL service by using this directive. | ||
```graphql | ||
type User @key(fields: "id") @extends{ | ||
id: ID! @external |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
id: ID! @external | |
id: String! @id @external |
Let's use this, so that we have both the syntax for @key
visible to users in docs.
content/graphql/federation/index.md
Outdated
parent = "graphql" | ||
+++ | ||
|
||
Dgraph supports Apollo federation starting in release version 21.03. This lets you create a gateway GraphQL service that includes the Dgraph GraphQL API and other GraphQL services. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dgraph supports Apollo federation starting in release version 21.03. This lets you create a gateway GraphQL service that includes the Dgraph GraphQL API and other GraphQL services. | |
Dgraph supports [Apollo federation](https://www.apollographql.com/docs/federation/) starting in release version 21.03. This lets you create a gateway GraphQL service that includes the Dgraph GraphQL API and other GraphQL services. |
``` | ||
|
||
When the gateway fetches `user.reviews` from the `review` service, the gateway will get `user.email` from the `User` service and provide it as an argument to the `_entities` query. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
About @requires
, we also need to add that:
If you feel the need to use `@requires`, you probably also want to add custom logic on such fields. You can do that using `@lambda`/`@custom(http: {...})`
See, this PR for example usage of @requires
with @lambda
and accordingly add an example here with @lambda
: dgraph-io/dgraph#7558
content/graphql/federation/index.md
Outdated
``` | ||
|
||
{{% notice "note" %}} | ||
Currently we only support federated queries, not federated mutations. We might support it in the future. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The apollo spec itself doesn't support federated mutations. So, I don't think we should even say that we might support them later.
content/graphql/federation/index.md
Outdated
Currently we only support federated queries, not federated mutations. We might support it in the future. | ||
{{% /notice %}} | ||
|
||
## Gateway supported directives |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel this section is also irrelevant to users. They shouldn't be concerned about the bugs in the underlying libs. They only want to use the feature.
So, let's remove this section too.
content/graphql/federation/index.md
Outdated
|
||
When adding an object of type `Astronaut`, first it should be added into `AstronautService` service and then the `addAstronaut` mutation should be called with value of `id` provided as an argument which must be equal to the value in `AstronautService` service. | ||
|
||
Use the admin endpoint to query for the generated schema - |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's remove the getGQLSchema
thing from here, it is not relevant.
content/graphql/federation/index.md
Outdated
### `@key` directive | ||
This directive takes one field argument inside it: the `@key` field. There are few limitations on how to use `@key` directives: | ||
|
||
- Users can define the @key directive only once for a type |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Users can define the @key directive only once for a type | |
- Users can define the `@key` directive only once for a type |
content/graphql/federation/index.md
Outdated
|
||
- Users can define the @key directive only once for a type | ||
- Support for multiple key fields is not currently available. | ||
- Since the @key field acts as a foreign key to resolve entities from the service where it is extended, the field provided as an argument inside the @key directive should be of ID type or have the @id directive on it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Since the @key field acts as a foreign key to resolve entities from the service where it is extended, the field provided as an argument inside the @key directive should be of ID type or have the @id directive on it. | |
- Since the `@key` field acts as a foreign key to resolve entities from the service where it is extended, the field provided as an argument inside the `@key` directive should be of `ID` type or have the `@id` directive on it. |
content/graphql/federation/index.md
Outdated
``` | ||
|
||
### `@extends` directive | ||
This directive is provided to give support for extended definitions. Suppose the above defined `User` type is defined in some other service. Users can extend it in Dgraph's GraphQL service by using this directive. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This directive is provided to give support for extended definitions. Suppose the above defined `User` type is defined in some other service. Users can extend it in Dgraph's GraphQL service by using this directive. | |
This directive provides support for extended definitions. For example, if the above-defined `User` type is defined in some other service, you can extend it in Dgraph's GraphQL service by using the `@extends` directive, as follows: |
content/graphql/federation/index.md
Outdated
products: [Product] | ||
} | ||
``` | ||
The same is also achievable with the `extend` keyword, i.e., user has the choice to choose between `extend type User ...` or `type User @extends ...`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The same is also achievable with the `extend` keyword, i.e., user has the choice to choose between `extend type User ...` or `type User @extends ...`. | |
You can also achieve this with the `extend` keyword; so you have a choice between two types of syntax to extend a type into your Dgraph GraphQL service: `extend type User ...` or `type User @extends ...`. |
content/graphql/federation/index.md
Outdated
The same is also achievable with the `extend` keyword, i.e., user has the choice to choose between `extend type User ...` or `type User @extends ...`. | ||
|
||
### `@external` directive | ||
This directive is used when the given field is not stored in this service. It can only be used on extended type definitions. As it is used above on the `id` field of `User` type. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This directive is used when the given field is not stored in this service. It can only be used on extended type definitions. As it is used above on the `id` field of `User` type. | |
You use this directive when the given field is not stored in this service. It can only be used on extended type definitions. For example, it is used in the example shown above on the `id` field of the `User` type. |
content/graphql/federation/index.md
Outdated
This directive is used when the given field is not stored in this service. It can only be used on extended type definitions. As it is used above on the `id` field of `User` type. | ||
|
||
### `@provides` directive | ||
This directive is used on a field that tells the gateway to return a specific fieldSet from the base type while fetching the field. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This directive is used on a field that tells the gateway to return a specific fieldSet from the base type while fetching the field. | |
You use this directive on a field that tells the gateway to return a specific fieldset from the base type while fetching the field. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Per https://www.apollographql.com/docs/federation/federation-spec/#scalar-_fieldset, we should either write "fieldset" or _FieldSet
. The first one makes more sense to me in this context, but I could be wrong.
content/graphql/federation/index.md
Outdated
} | ||
``` | ||
|
||
While fetching `Review.product` from the `review` service, and if the `name` or `price` is also queried, the gateway will fetch these from the `review` service itself, meaning that it also resolves these fields, even though both fields are `@external`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While fetching `Review.product` from the `review` service, and if the `name` or `price` is also queried, the gateway will fetch these from the `review` service itself, meaning that it also resolves these fields, even though both fields are `@external`. | |
While fetching `Review.product` from the `review` service, and if the `name` or `price` is also queried, the gateway will fetch these from the `review` service itself. So, the `review` service also resolves these fields, even though both fields are `@external`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Breaking this into two sentences makes it easier to parse (and machine-translate)
content/graphql/federation/index.md
Outdated
While fetching `Review.product` from the `review` service, and if the `name` or `price` is also queried, the gateway will fetch these from the `review` service itself, meaning that it also resolves these fields, even though both fields are `@external`. | ||
|
||
### `@requires` directive | ||
This directive is used on a field to annotate the fieldSet of the base type. It is used to develop a query plan where the required fields may not be needed by the client, but the service may need additional information from other services. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This directive is used on a field to annotate the fieldSet of the base type. It is used to develop a query plan where the required fields may not be needed by the client, but the service may need additional information from other services. | |
You use this directive on a field to annotate the fieldset of the base type. You can use it to develop a query plan where the required fields may not be needed by the client, but the service may need additional information from other services. |
content/graphql/federation/index.md
Outdated
|
||
When the gateway fetches `user.reviews` from the `review` service, the gateway will get `user.email` from the `User` service and provide it as an argument to the `_entities` query. | ||
|
||
Using `@requires` alone on a field doesn't make much sense. In cases, where you feel the need to use `@requires`, you would want some custom logic on that field too. You can achieve that using `@lambda` or `@custom(http: {...})` directives. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using `@requires` alone on a field doesn't make much sense. In cases, where you feel the need to use `@requires`, you would want some custom logic on that field too. You can achieve that using `@lambda` or `@custom(http: {...})` directives. | |
Using `@requires` alone on a field doesn't make much sense. In cases where you need to use `@requires`, you should also add some custom logic on that field. You can add such logic using the `@lambda` or `@custom(http: {...})` directives. |
content/graphql/federation/index.md
Outdated
} | ||
``` | ||
|
||
The queries for `Astronaut` are not exposed to the gateway since it will be resolved through the `_entities` resolver. Although these queries will be available on the Dgraph GraphQL API endpoint. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The queries for `Astronaut` are not exposed to the gateway since it will be resolved through the `_entities` resolver. Although these queries will be available on the Dgraph GraphQL API endpoint. | |
The queries for `Astronaut` are not exposed to the gateway because they are resolved through the `_entities` resolver. However, these queries are available on the Dgraph GraphQL API endpoint. |
content/graphql/federation/index.md
Outdated
|
||
## Mutation for `extended` types | ||
If you want to add an object of `Astronaut` type which is extended in this service. | ||
The mutation `addAstronaut` takes `AddAstronautInput` which is generated as - |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The mutation `addAstronaut` takes `AddAstronautInput` which is generated as - | |
The mutation `addAstronaut` takes `AddAstronautInput`, which is generated as follows: |
content/graphql/federation/index.md
Outdated
} | ||
``` | ||
|
||
Even though the `id` field is of `ID` type which should be ideally generated internally by Dgraph. In this case, it should be provided as input since currently federated mutations aren't supported. The user should provide the value of `id` same as the value present in the GraphQL service where the type `Astronaut` is defined. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even though the `id` field is of `ID` type which should be ideally generated internally by Dgraph. In this case, it should be provided as input since currently federated mutations aren't supported. The user should provide the value of `id` same as the value present in the GraphQL service where the type `Astronaut` is defined. | |
The `id` field is of `ID` type, which is usually generated internally by Dgraph. In this case, it's provided as an input because federated mutations aren't currently supported. The user should provide the same `id` value that is present in the GraphQL service where the type `Astronaut` is defined. |
content/graphql/federation/index.md
Outdated
|
||
Even though the `id` field is of `ID` type which should be ideally generated internally by Dgraph. In this case, it should be provided as input since currently federated mutations aren't supported. The user should provide the value of `id` same as the value present in the GraphQL service where the type `Astronaut` is defined. | ||
|
||
For example, let's take that the type `Astronaut` is defined in some other service `AstronautService` as - |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For example, let's take that the type `Astronaut` is defined in some other service `AstronautService` as - | |
For example, let's assume that the type `Astronaut` is defined in some other service, `AstronautService`, as follows: |
content/graphql/federation/index.md
Outdated
} | ||
``` | ||
|
||
When adding an object of type `Astronaut`, first it should be added into `AstronautService` service and then the `addAstronaut` mutation should be called with value of `id` provided as an argument which must be equal to the value in `AstronautService` service. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When adding an object of type `Astronaut`, first it should be added into `AstronautService` service and then the `addAstronaut` mutation should be called with value of `id` provided as an argument which must be equal to the value in `AstronautService` service. | |
When adding an object of type `Astronaut`, you should first add it to the `AstronautService` service. Then, you can call the `addAstronaut` mutation with the value of `id` provided as an argument that must be equal to the value in `AstronautService` service. |
Approved with suggested edits. You might want to add a "Known Issues" section at the bottom that will make it easy to see the limitation around mutations at-a-glance (especially if there are any other limitations that we want to highlight). |
@aaroncarey Abhimanyu mentioned that those things aren't supported by Apollo federation itself and hence it isn't a limitation, we shouldn't be mentioning it. |
Docs regarding support for Apollo federation.
Fixes DOC-156