9. Connecting data using entities


The foundation of our is complete. We've separated FlyBy's into location data and review data, and we've implemented s that only define the types they're concerned with.

Revisiting our agreement checklist, we still have three s that we don't know how to implement yet:

  • Location.reviewsForLocation and Location.overallRating: These are both s of the Location type, but we decided we want them to be owned by the reviews .
  • Review.location: This is a on the Review type (which lives in the reviews ), but the has a return type of Location, which is defined in the locations .
The FlyBy schema diagram, with the three remaining fields in focus

To implement these s, we need to add a new tool to our developer tool belts: entities!

In this lesson, we will:

  • Learn what an entity is and what it's used for
  • Learn how to define an entity
  • Learn how the represents entities when it talks between s

What's an entity?

An entity is an with s split between multiple s.

This means we can define a type that both of our s can contribute s to and resolve independently.

Illustration of 2 subgraphs contributing fieleds to an entity.

In FlyBy, we want our reviews to include the location that they are written about. Our Location type needs to be used by both s, so we'll be turning the Location type into an entity.

A that defines an entity can do one or both of the following:

  1. Reference the entity
  2. Contribute s to the entity

Reference the entity

Referencing an entity means using it as a return type for another defined in the .

For example, in the reviews , we can add a location to the Review type, which will reference the Location entity as its return type.

The Review type, with a location field that has a return value of a Location type

Contribute fields to the entity

Contributing s to an entity means that one adds new fields to an entity that are specific to that subgraph's concerns.

For example, the Location entity will have s for name, description, and photo, which will live in the locations . In other words, the locations contributes these s to the Location entity.

And the reviews contributes two review-specific s to the Location entity: reviewsForLocation and overallRating.

The Location entity, with fields divided between the locations and reviews subgraph

How to create an entity

To convert an object into an entity in the , we need to do two things:

  1. Define a primary key
  2. Define a reference resolver

Defining a primary key

An entity's primary key is the (or fields) that can uniquely identify an instance of that entity within a . The uses primary keys to collect data from across multiple subgraphs and associate it with a single entity instance.

For example, a location entity's primary key is its id. The uses that id to collect data about a specific location instance, like a location with id "loc-1".

Illustration showing three entities with unique ids

In each of our s, we can define a primary key for an entity, by adding the @key after the type's name.

The @key needs a property called fields, which we'll set to the we want to use as the entity's primary key.

Entity syntax
type EntityType @key(fields: "id")
Illustration showing the syntax for defining an entity. See code snippet above for an example.

Defining a reference resolver function

Each that contributes s to an entity also needs to define a special function for that entity called a reference resolver. The uses reference s to directly access the entity s that each contributes.

Illustration of each subgraph contributing fields to an entity with an associated reference resolver.

Every reference has the name: __resolveReference. We define each entity's reference right alongside all the resolvers for that type.

The __resolveReference function has a slightly different signature from other functions. Instead of the usual four s, __resolveReference only takes three:

  • reference: The entity representation object that's passed in by the . This tells the which instance of an entity is being requested. We'll cover what an entity representation is in the section below.
  • context: The object shared across all s. (This is the same as in normal resolvers, but note that by convention, we refer to this __resolveReference as context, rather than contextValue as in other s!)
  • info: Contains information about the 's execution state, just like in a normal . We won't use this much.
Illustration of each subgraph contributing fields to an entity with an associated reference resolver.

Let's focus on this first , reference, and learn more about entity representations.

What's an entity representation?

An entity representation is an object that the uses to represent a specific instance of an entity. A representation always includes the typename for that entity and the @key for the specific instance.

  • The __typename field: This exists on all GraphQL types automatically. It always returns the name of its containing type, as a string. For example, Location.__typename returns "Location".
  • The @key field: The key-value pair that a can use to identify the instance of an entity. For example, if we defined the Location entity using the "id" as a primary key, then our entity representation would include an "id" property with a value like "loc-2".

An entity representation for a location might look like this:

Example location entity representation
"__typename": "Location",
"id": "loc-2"

You can think of an entity representation as a passport that the uses to refer to a particular object between s.

The typename is like a passport's country of origin. It says which entity the object belongs to. And the @key is like a passport's ID number, uniquely identifying this instance of that entity.

The representation object is like a passport


Where should an entity's __resolveReference function be defined?
Check your understanding!
An entity's primary key is used to identify a unique instance of that entity within a 
. To define a primary key, apply the 
 directive and pass in the name of the primary key field as the value of the 
 property. An entity can have 
 primary key.

Drag items from this box to the blanks above

  • fields

  • @unique

  • router

  • only one

  • @primary

  • more than one

  • subgraph

  • reference resolver

  • @key

  • keys

Key takeaways

  • An entity is a type that can resolve its s across multiple s.
  • To create an entity, we can use the @key to specify which (s) can uniquely identify an object of that type.
  • We can use entities in two ways:
    • As a return type for a (referencing an entity).
    • Defining s for an entity from multiple s (contributing to an entity).
  • Any that contributes s to an entity needs to define a reference function for that entity. This __resolveReference is called whenever the needs to access s of the entity from within another .
  • An entity representation is an object that the uses to represent a specific instance of an entity. It includes the entity's type and its key (s).

Up next

We've covered a lot about entities! In the next lesson, we'll jump back into the code for our s and define our first entity.


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.