Odyssey

Voyage I: Federation from Day One

Intro to FederationProject setupAgreeing on a schemaBuilding out the subgraphsManaged federation & the supergraphPublishing the subgraphs with RoverHow the router resolves dataRouter configuration and UplinkConnecting data using entitiesDefining an entityEntities and the query planReferencing an entityContributing to an entityPutting it all together
10. Defining an entity
3m

Overview

Let's jump into the code!

In this lesson, we will:

  • Convert the Location type into an entity that can be shared between our subgraphs
  • Publish updates to existing subgraphs

✏️ Defining the Location entity's @key

  1. Open up the subgraph-locations/locations.graphql file and find the Location type.

    subgraph-locations/locations.graphql
    type Location {
    id: ID!
    "The name of the location"
    name: String!
    "A short description about the location"
    description: String!
    "The location's main photo as a URL"
    photo: String!
    }
  2. We'll add the @key directive to this type definition, specifying the fields property and setting its value to id.

    subgraph-locations/locations.graphql
    type Location @key(fields: "id") {
    id: ID!
    "The name of the location"
    name: String!
    "A short description about the location"
    description: String!
    "The location's main photo as a URL"
    photo: String!
    }

Check changes in Sandbox

Let's test our changes. Open up http://localhost:4001 in your browser and use Sandbox to query our server again.

In the Documentation tab, we should now see that there's a new field on the Query type called _entities. This is a special field that the router uses for coordinating data between subgraphs. We'll learn how exactly the router uses this field in the next lesson.

studio.apollographql.com/sandbox/explorer
The Location subgraph displaying an _entities field

Other than that, not much has changed! We should still be able to use Explorer to query the locations subgraph as before. (Try running a quick query for some data on the locations field, to make sure everything still works as expected.)

Publish the locations subgraph

We'll need to publish this subgraph so that the schema registry can pick up our changes.

Let's make sure we're in the top-level directory of our project when we run the rover subgraph publish command in the terminal.

rover subgraph publish <APOLLO_GRAPH_REF> \
--name locations \
--schema ./subgraph-locations/locations.graphql

We can omit the --routing-url option in the command because we already set that value the first time we published the subgraph to the registry.

Great, it looks like our changes have been published successfully!

✏️ Defining our entity in reviews

We want to use the Location entity in our reviews subgraph as well.

  1. Open up the subgraph-reviews/reviews.graphql file.

  2. We'll add the Location type definition, along with the @key directive and set the id field as the primary key.

    subgraph-reviews/reviews.graphql
    type Location @key(fields: "id") {
    # to fill in
    }
  3. Inside the curly braces, we'll add the id field of type non-nullable ID!.

    subgraph-reviews/reviews.graphql
    type Location @key(fields: "id") {
    id: ID!
    }

    The Location entity doesn't need to include all the fields we defined for it in the locations subgraph. After all, the reviews subgraph doesn't know anything about these fields, or how to resolve them!

    So far, we've given our reviews subgraph a stub of the Location entity. A stub serves as a basic representation of a type that includes just enough information to work with that type in the subgraph.

    There's one more change we need to make. Because the reviews subgraph is not responsible for resolving any of the entity's other fields, we'll add one more property to our @key directive.

  4. Inside the @key directive, add a property called resolvable and set it to false.

    subgraph-reviews/reviews.graphql
    type Location @key(fields: "id", resolvable: false) {
    id: ID!
    }

    This property tells the router that this subgraph doesn't define a reference resolver for this entity.

    Recall that a reference resolver is responsible for returning all of the entity fields that this subgraph contributes. The reviews subgraph doesn't contribute any other fields (besides the key field), so it doesn't need to define a reference resolver. The resolvable: false property indicates this to the router!

Publish the reviews subgraph

Now let's publish our reviews subgraph updates. From a terminal in the root directory of our project, let's run the rover subgraph publish command again.

rover subgraph publish <APOLLO_GRAPH_REF> \
--name reviews \
--schema ./subgraph-reviews/reviews.graphql

Alright, we see a success message and our changes have made it to the registry!

Practice

Code Challenge!

Convert the Book type below into an entity. A Book can be uniquely identified by its International Standard Book Number (ISBN).

Loading...
Loading initial values

Key takeaways

  • To create an entity, we can use the @key directive to specify which field(s) can uniquely identify an object of that type.
  • When a subgraph can't be used to resolve any non-@key fields of an entity, we pass resolvable: false to the @key directive definition.

Up next

We've added entities to our subgraph schemas and published our changes!

In the next lesson, we'll learn how the router uses entities and entity representations to connect data from multiple subgraphs.

Previous
Next

Share your questions and comments about this lesson

Your feedback helps us improve! If you're stuck or confused, let us know and we'll help you out. All comments are public and must follow the Apollo Code of Conduct. Note that comments that have been resolved or addressed may be removed.

You'll need a GitHub account to post below. Don't have one? Post in our Odyssey forum instead.

              entity

              An object type of Apollo Federation that can be fetched with one or more unique keys. Can resolve its fields from multiple data sources in a federated graph.

              subgraph

              A service in a federated GraphQL architecture. Acts as a module for a supergraph. Includes both GraphQL services and REST services integrated via Apollo Connectors.

              subgraph

              A service in a federated GraphQL architecture. Acts as a module for a supergraph. Includes both GraphQL services and REST services integrated via Apollo Connectors.

              directive

              A GraphQL annotation for a schema or operation that customizes request execution. Prefixed with @ and may include arguments. For example, the @lowerCase directive below can define logic to return the username field in lowercase:

              type User {
              username: String! @lowerCase
              }
              query

              A request for specific data from a GraphQL server. Clients define the structure of the response, enabling precise and efficient data retrieval.

              field

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              Query

              A request for specific data from a GraphQL server. Clients define the structure of the response, enabling precise and efficient data retrieval.

              field

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              router

              The single access point for a federated GraphQL architecture. It receives incoming operations and intelligently routes them across component services before returning a unified response.

              subgraphs

              A service in a federated GraphQL architecture. Acts as a module for a supergraph. Includes both GraphQL services and REST services integrated via Apollo Connectors.

              query

              A request for specific data from a GraphQL server. Clients define the structure of the response, enabling precise and efficient data retrieval.

              subgraph

              A service in a federated GraphQL architecture. Acts as a module for a supergraph. Includes both GraphQL services and REST services integrated via Apollo Connectors.

              query

              A request for specific data from a GraphQL server. Clients define the structure of the response, enabling precise and efficient data retrieval.

              field

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              subgraph

              A service in a federated GraphQL architecture. Acts as a module for a supergraph. Includes both GraphQL services and REST services integrated via Apollo Connectors.

              subgraph

              A service in a federated GraphQL architecture. Acts as a module for a supergraph. Includes both GraphQL services and REST services integrated via Apollo Connectors.

              entity

              An object type of Apollo Federation that can be fetched with one or more unique keys. Can resolve its fields from multiple data sources in a federated graph.

              subgraph

              A service in a federated GraphQL architecture. Acts as a module for a supergraph. Includes both GraphQL services and REST services integrated via Apollo Connectors.

              directive

              A GraphQL annotation for a schema or operation that customizes request execution. Prefixed with @ and may include arguments. For example, the @lowerCase directive below can define logic to return the username field in lowercase:

              type User {
              username: String! @lowerCase
              }
              field

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              field

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              entity

              An object type of Apollo Federation that can be fetched with one or more unique keys. Can resolve its fields from multiple data sources in a federated graph.

              fields

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              subgraph

              A service in a federated GraphQL architecture. Acts as a module for a supergraph. Includes both GraphQL services and REST services integrated via Apollo Connectors.

              subgraph

              A service in a federated GraphQL architecture. Acts as a module for a supergraph. Includes both GraphQL services and REST services integrated via Apollo Connectors.

              fields

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              subgraph

              A service in a federated GraphQL architecture. Acts as a module for a supergraph. Includes both GraphQL services and REST services integrated via Apollo Connectors.

              entity

              An object type of Apollo Federation that can be fetched with one or more unique keys. Can resolve its fields from multiple data sources in a federated graph.

              subgraph

              A service in a federated GraphQL architecture. Acts as a module for a supergraph. Includes both GraphQL services and REST services integrated via Apollo Connectors.

              subgraph

              A service in a federated GraphQL architecture. Acts as a module for a supergraph. Includes both GraphQL services and REST services integrated via Apollo Connectors.

              entity

              An object type of Apollo Federation that can be fetched with one or more unique keys. Can resolve its fields from multiple data sources in a federated graph.

              fields

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              directive

              A GraphQL annotation for a schema or operation that customizes request execution. Prefixed with @ and may include arguments. For example, the @lowerCase directive below can define logic to return the username field in lowercase:

              type User {
              username: String! @lowerCase
              }
              directive

              A GraphQL annotation for a schema or operation that customizes request execution. Prefixed with @ and may include arguments. For example, the @lowerCase directive below can define logic to return the username field in lowercase:

              type User {
              username: String! @lowerCase
              }
              router

              The single access point for a federated GraphQL architecture. It receives incoming operations and intelligently routes them across component services before returning a unified response.

              subgraph

              A service in a federated GraphQL architecture. Acts as a module for a supergraph. Includes both GraphQL services and REST services integrated via Apollo Connectors.

              reference resolver

              A type of resolver function responsible for resolving references to an entity within a federated GraphQL schema. Also known as an entity resolver.

              entity

              An object type of Apollo Federation that can be fetched with one or more unique keys. Can resolve its fields from multiple data sources in a federated graph.

              reference resolver

              A type of resolver function responsible for resolving references to an entity within a federated GraphQL schema. Also known as an entity resolver.

              entity

              An object type of Apollo Federation that can be fetched with one or more unique keys. Can resolve its fields from multiple data sources in a federated graph.

              fields

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              subgraph

              A service in a federated GraphQL architecture. Acts as a module for a supergraph. Includes both GraphQL services and REST services integrated via Apollo Connectors.

              subgraph

              A service in a federated GraphQL architecture. Acts as a module for a supergraph. Includes both GraphQL services and REST services integrated via Apollo Connectors.

              fields

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              reference resolver

              A type of resolver function responsible for resolving references to an entity within a federated GraphQL schema. Also known as an entity resolver.

              router

              The single access point for a federated GraphQL architecture. It receives incoming operations and intelligently routes them across component services before returning a unified response.

              subgraph

              A service in a federated GraphQL architecture. Acts as a module for a supergraph. Includes both GraphQL services and REST services integrated via Apollo Connectors.

              entity

              An object type of Apollo Federation that can be fetched with one or more unique keys. Can resolve its fields from multiple data sources in a federated graph.

              directive

              A GraphQL annotation for a schema or operation that customizes request execution. Prefixed with @ and may include arguments. For example, the @lowerCase directive below can define logic to return the username field in lowercase:

              type User {
              username: String! @lowerCase
              }
              field

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              subgraph

              A service in a federated GraphQL architecture. Acts as a module for a supergraph. Includes both GraphQL services and REST services integrated via Apollo Connectors.

              fields

              A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.

              type Author {
              # id, firstName, and lastName are all fields of the Author type
              id: Int!
              firstName: String
              lastName: String
              }
              entity

              An object type of Apollo Federation that can be fetched with one or more unique keys. Can resolve its fields from multiple data sources in a federated graph.

              directive

              A GraphQL annotation for a schema or operation that customizes request execution. Prefixed with @ and may include arguments. For example, the @lowerCase directive below can define logic to return the username field in lowercase:

              type User {
              username: String! @lowerCase
              }
              entities

              An object type of Apollo Federation that can be fetched with one or more unique keys. Can resolve its fields from multiple data sources in a federated graph.

              subgraph schemas

              A schema for a subgraph server. A subgraph schema must be compliant with the GraphQL and Apollo Federation specs to be composed into a supergraph.

              router

              The single access point for a federated GraphQL architecture. It receives incoming operations and intelligently routes them across component services before returning a unified response.

              entities

              An object type of Apollo Federation that can be fetched with one or more unique keys. Can resolve its fields from multiple data sources in a federated graph.

              entity

              An object type of Apollo Federation that can be fetched with one or more unique keys. Can resolve its fields from multiple data sources in a federated graph.

              subgraphs

              A service in a federated GraphQL architecture. Acts as a module for a supergraph. Includes both GraphQL services and REST services integrated via Apollo Connectors.

              NEW COURSE ALERT

              Introducing Apollo Connectors

              Connectors are the new and easy way to get started with GraphQL, using existing REST APIs.

              Say goodbye to GraphQL servers and resolvers—now, everything happens in the schema!

              Take the course