Docs
Launch GraphOS Studio

Thinking in entities

federationschema-design

💡 TIP

If you're an enterprise customer looking for more material on this topic, try the Enterprise best practices: Schema design course on Odyssey.

Not an enterprise customer? Learn about GraphOS for Enterprise.

Thinking entities

Entities are the core building blocks of a federated graph, so the adoption of any design best practice must be approached with the unique role of entities in mind. While there's no requirement for s to define any entities at all with Apollo Federation, the federated schema design process often begins by thinking about what the initial entity types will be and how they will be referenced and extended throughout the graph to help preserve the separation of concerns between subgraphs both today and as the graph evolves in the future.

Define, reference, and extend entities as needed

The Apollo Federation specification indicates that an Object or Interface type can be made into an entity by adding the @key to its definition in a . The @key defines a primary key for the entity and its fields will contain one or more of the type's s. In the following example, the Product entity's primary key would be its upc :

Products Subgraph
type Product @key(fields: "upc") {
upc: String!
name: String!
description: String
}

In other words, setting the upc as the key means that other s that want to use this entity will need to know at least that value for any product. The keys we define should be values that uniquely identify a resource. This is because we want to avoid scenarios where they are used to arbitrarily pass dynamic field data around query execution between subgraphs.

After defining an entity in a , other s can reference that entity in their schemas. In order for the referencing subgraph's schema to be valid, it must define a stub of the entity in its schema. For example, we can reference a Product type defined in the products as the return type corresponding to a product on a Review type defined in reviews :

Reviews Subgraph
type Review {
rating: Int
product: Product
}
type Product @key(fields: "upc") {
upc: String!
}

The @key indicates that the reviews will be able to identify a product by its UPC value and therefore be able to connect to a product based on its upc primary key , but the reviews does not need to be aware of any other details about a given product.

Referencing entities is a key feature of federation, but it's only half of the story. While an entity will be owned by a single , other subgraphs might wish to add additional s to the entity's type to provide a more holistic representation of the entity in the graph. Doing so is a simple as adding the additional field to the extended type in a non-originating subgraph. For example, a reviews subgraph's might add a reviews to the extended Product type that was originally defined in the products :

Reviews Subgraph
type Review {
rating: Int
product: Product
}
type Product @key(fields: "upc") {
upc: String!
reviews: [Review]
}

When extending entities, it's important to keep in mind that the entity's originating subgraph will not be aware of the added fields. Additionally, each in an entity must only be defined once or the gateway will encounter composition errors.

Work from the entities outward

When migrating from a client-only or monolithic GraphQL pattern, that work begins by identifying what entities will be exposed in the first extracted from the larger . When migrating from an architecture consisting of BFF-based GraphQL APIs or any other architecture of multiple overlapping graphs, the work of identifying entities (and determining new subgraph boundaries, in general) might be a bit more complex and involve some degree of negotiation with respect to type ownership, as well as a migration process to help account for any breaking changes that might result for clients.

Whatever your architectural starting point, Apollo Federation was designed to allow the work of identifying entities and defining boundaries to be done in an incremental, non-disruptive fashion. Beginning to identify these entities is also the essential prerequisite for adopting the other design best practices that will follow.

For more information on entity usage and capabilities, please see the Entities documentation page.

@defer and Entities

Entities aren't just useful for connecting data across s. You can also use entities to enable the new @defer directive for client-controlled prioritization of response data. The Apollo can defer resolution of fields in entities (and root s) and handle sending data back to the client in prioritized chunks. By defining types as entities within your graph, clients can improve perceived user experience by adding a to their s.

Next
Home
Edit on GitHubEditForumsDiscord