4.3 KiB
Apollo Federation
Apollo Federation
is a GraphQL
API gateway which can combine multiple GraphQL services, allowing each service to implement the subset of the API it is responsible for. You can read more in the official documentation.
Async-graphql
supports all the functionality of Apollo Federation
, but some modifications to your Schema
are required.
-
You can use the
extends
property declaration onasync_graphql::Object
andasync_graphql::Interface
to extend a type offered by another implementing service. -
The
external
property declares that a field comes from another service。 -
The
provides
directive is used to annotate the expected returned fieldset from a field on a base type that is guaranteed to be selectable by the gateway. -
The
requires
directive is used to annotate the required input fieldset from a base type for a resolver. 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. -
The
shareable
directive is used to indicate that an object type's field is allowed to be resolved by multiple subgraphs (by default, each field can be resolved by only one subgraph). -
The
inaccessible
directive is used to indicate that a location in the schema cannot be queried at the supergraph level, but can still be queried at the subgraph level. -
The
tag
directive is used to provide a mechanism for applying arbitrary string metadata to the fields and types of a schema. Tags will be propagated up into composed supergraphs. -
The
override
directive is used to indicate that a field is now to be resolved by the current subgraph instead of the named subgraph. -
The
link
directive is needed in order to indicate that the subgraph is Federation v2 compatible, enabling theshareable
,inaccessable
, andoverride
directives.
Enabling Federation v2 using the link directive
async-graphql provides a configuration function enable_apollo_fed2_link
on the schema builder to have it print out an extend schema
element with an appropriately configured link
directive whenever the federation schema is requested.
Schema::build(Query, EmptyMutation, EmptySubscription)
.enable_apollo_fed2_link()
.finish()
and the following (or similar) will be attached to the schema:
extend schema @link(
url: "https://specs.apollo.dev/federation/v2.0",
import: ["@key", "@tag", "@shareable", "@inaccessible", "@override", "@external", "@provides", "@requires"]
)
Entity lookup function
# extern crate async_graphql;
# use async_graphql::*;
# #[derive(SimpleObject)]
# struct User { id: ID }
struct Query;
#[Object]
impl Query {
#[graphql(entity)]
async fn find_user_by_id(&self, id: ID) -> User {
User { id }
}
#[graphql(entity)]
async fn find_user_by_id_with_username(&self, #[graphql(key)] id: ID, username: String) -> User {
User { id }
}
#[graphql(entity)]
async fn find_user_by_id_and_username(&self, id: ID, username: String) -> User {
User { id }
}
}
Notice the difference between these three lookup functions, which are all looking for the User
object.
-
find_user_by_id
Use
id
to find anUser
object, the key forUser
isid
. -
find_user_by_id_with_username
Use
id
to find anUser
object, the key forUser
isid
, and theusername
field value of theUser
object is requested. -
find_user_by_id_and_username
Use
id
andusername
to find anUser
object, the keys forUser
areid
andusername
.
For a complete example, refer to: https://github.com/async-graphql/examples/tree/master/federation.
Defining a compound primary key
A single primary key can consist of multiple fields, and even nested fields, you can use InputObject
to implements a nested primary key.
In the following example, the primary key of the User
object is key { a b }
.
# extern crate async_graphql;
# use async_graphql::*;
# #[derive(SimpleObject)]
# struct User { id: i32 }
#[derive(InputObject)]
struct NestedKey {
a: i32,
b: i32,
}
struct Query;
#[Object]
impl Query {
#[graphql(entity)]
async fn find_user_by_key(&self, key: NestedKey) -> User {
User { id: key.a }
}
}