Rover's giving us some build errors: we've got fields in our schema that are missing instructions—and that's a job for the @connectdirective.
In this lesson, we will:
Learn about the @connectdirective syntax
Use @connect to retrieve data for a Queryfield
A closer look at @connect
The @connectdirective describes how to get the data for a GraphQLfield from a REST endpoint.
@connect takes in four parameters:
source: a unique identifier for the data source. This should be the same as the name value we defined in the @sourcedirective.
http: an object that defines the HTTP request to make, including HTTP method and path.
selection: where we map the API's JSON response to GraphQLfields
entity: If we set this to true, this Connector can provide instructions on how to retrieve the data for the entity's fields. We'll learn more about entities in a later lesson.
When we extend our schema with the Connectors spec, each root field requires a @connectdirective. By root field, we mean the fields on the Query and Mutation types, which are the entry points to a GraphQL API.
Let's see @connect in action.
Importing the @connect directive
To start, we'll need to let our schema know about the directive.
At the top of the listings.graphql schema, where we imported the source directive from the Connectors spec, let's add @connect.
listings.graphql
@link(
url:"https://specs.apollo.dev/connect/v0.1"
import:["@source","@connect"]
)
@connect and featured listings
Now we're ready to use it!
Let's find the featuredListingsfield under the Query type. Rover was complaining about this field in particular not having a @connectdirective, so let's add it.
listings.graphql
typeQuery{
"A curated array of listings to feature on the homepage"
featuredListings:[Listing!]!
}
We'll take advantage of the auto-complete the Apollo VS Code extension gives us. Type @connect and hit Enter and we'll get all the directive parameters ready to be filled in.
listings.graphql
featuredListings:[Listing!]!
@connect(
source:""
http:{GET:""}
selection:"""
"""
)
First, the source. Let's set the value to the same one we defined at the top.
listings.graphql
source:"listings"
Next up is the http parameter, where we'll need to indicate what endpoint we're sending the request to. Let's take a moment to review our mockup and the REST API endpoint we'll need.
GET /featured-listings
Airlock's homepage needs to display a grid of featured listings along with a few properties.
In this lesson, we're starting small and tackling the id and titlefields first.
Mapping this back to our REST API, we'll need to retrieve this data from the GET /featured-listings endpoint. We can examine the response from that endpoint here: https://airlock-listings.demo-api.apollo.dev/featured-listings. We see an array of listing objects with a bunch of different properties.
Now how do we take this data and connect it to our GraphQL schema?
The http request
The http parameter is already set to a GET request, so all we need to do is add the /featured-listings endpoint.
listings.graphql
http:{GET:"/featured-listings"}
Finally, we just have selection left!
The selection mapping
Remember, selection defines the mapping from the JSON response to our schema fields.
In our schema, the featuredListingsfield returns an array of Listing types. Each Listing type requires an id and title.
As we can see in our REST API response, those two properties are already returned for each item in the array. These are exactly the properties we need, named exactly how we want them! A simple one-to-one mapping.
REST API response
[
{
"id":"listing-1",
"title":"Cave campsite in snowy MoundiiX",
"numOfBeds":2,
"costPerNight":120,
"closedForBookings":false,
"amenities":[
{
"id":"am-2"
},
{
"id":"am-10"
},
{
"id":"am-11"
}
// more amenities
]
}
// more featured listings
]
Let's add them to the selection, inside these triple quotes.
"A curated array of listings to feature on the homepage"
featuredListings:[Listing!]!
@connect(
source:"listings"
http:{GET:"/featured-listings"}
selection:"""
id
title
"""
)
}
"A particular intergalactic location available for booking"
typeListing{
id:ID!
"The listing's title"
title:String!
}
Checking our work
All right, let's save our changes. We should see those pesky errors go away; Rover says the schema is good to go and the router is all set at http://localhost:4000.
We're going to use the Sandbox Explorer as our client here, kind of acting as a stand-in for whatever is going to send requests to our API. This could be something like a web page, a mobile app, or even a chatbot.
Using the sidebar, we'll build our request, also known as a GraphQLoperation.
We'll ask for our featuredListings by clicking on the plus icon, along with the pieces of data we'll need to satisfy our mockup: the id and title.
http://localhost:4000
http://localhost:4000
Our starter rover init template included an example products schema, which we won't need for this course. If you'd like to hide the products schema, follow the steps below. This is optional!
Open up the products.graphql file. At the top of the file, we'll import the @inaccessibledirective from the Federation spec. Make sure it's in the Federation imports, not Connectors!
products.graphql
extendschema
@link(# Enable this schema to use Apollo Federation features
url:"https://specs.apollo.dev/federation/v2.10"
import:["@inaccessible"]
)
@link(# Enable this schema to use Apollo Connectors
url:"https://specs.apollo.dev/connect/v0.1"
import:["@connect","@source"]
)
Then, we'll use that directive on the Query.productsfield.
products.graphql
typeQuery{
# The Query.products field uses @connect to connect to the /products endpoint in the "ecomm" source.
# To check out the JSON response for this endpoint, go to 🔗 https://ecommerce.demo-api.apollo.dev/products.
products:[Product]
@inaccessible
# A @connect directive defines the API data source of a GraphQL schema field.
While we're here, we can rename this operation to GetFeaturedListings. Your operation should look like this:
GetFeaturedListings operation
queryGetFeaturedListings{
featuredListings{
id
title
}
}
Let's run this thing! And we get data back; look at these fun space locations we can visit!
http://localhost:4000
Response data
{
"data":{
"featuredListings":[
{
"id":"listing-1",
"title":"Cave campsite in snowy MoundiiX"
},
{
"id":"listing-2",
"title":"Cozy yurt in Mraza"
},
{
"id":"listing-3",
"title":"Repurposed mid century aircraft in Kessail"
}
]
}
}
Task!
We've set the foundations. With one request from the client in the form of a GraphQLquery, the router takes care of retrieving and returning just that data from an underlying REST API, all through the Connector we built! As we grow our schema, we'll see just how powerful Connectors can be.
Lesson tasks
Practice
Which of the following @connect directive parameters should you use to map the endpoint's specific JSON properties to your GraphQL schema?
Use the REST API JSON response below to complete the code challenge.
REST API JSON response
{
"id":"px-m012",
"name":"Mraza",
"mass":6.42
}
HINT: @connect boilerplate code
@connect(
source:""
http:{GET:""}
selection:"""
# TODO
"""
)
Code Challenge!
Add the @connect directive to the Query.popularPlanets field. Use the outerspace source and the API endpoint GET /planets?sort=popular. Refer to the JSON object above and the existing schema to define the selection.
Loading...
Loading progress
Key takeaways
The @connectdirective describes how to get the data for a particular GraphQLfield using a defined source.
Each root field (the fields on the Query and Mutation types) requires a @connectdirective.
We use @connect's http parameter to define the HTTP method and URL parameters on the source that should be used to retrieve data for a field.
We use @connect's selection parameter to map the REST API's JSON response to our GraphQLfields.
Up next
We started small with just a couple of fields, but there's more to show! Let's add more fields and see what happens when our mapping doesn't quite match one-to-one.
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.
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:
typeUser{
username:String!@lowerCase
}
GraphQL
An open-source query language and specification for APIs that enables clients to request specific data, promoting efficiency and flexibility in data retrieval.
field
A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.
typeAuthor{
# 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.
typeAuthor{
# 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:
typeUser{
username:String!@lowerCase
}
field
A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.
typeAuthor{
# id, firstName, and lastName are all fields of the Author type
id:Int!
firstName:String
lastName:String
}
GraphQL
An open-source query language and specification for APIs that enables clients to request specific data, promoting efficiency and flexibility in data retrieval.
fields
A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.
typeAuthor{
# id, firstName, and lastName are all fields of the Author type
id:Int!
firstName:String
lastName:String
}
fields
A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.
typeAuthor{
# id, firstName, and lastName are all fields of the Author type
id:Int!
firstName:String
lastName:String
}
Rover
Apollo's command-line interface for managing and maintaining graphs with GraphOS.
fields
A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.
typeAuthor{
# 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:
typeUser{
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:
typeUser{
username:String!@lowerCase
}
field
A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.
typeAuthor{
# 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:
typeUser{
username:String!@lowerCase
}
GraphQL
An open-source query language and specification for APIs that enables clients to request specific data, promoting efficiency and flexibility in data retrieval.
field
A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.
typeAuthor{
# 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:
typeUser{
username:String!@lowerCase
}
GraphQL
An open-source query language and specification for APIs that enables clients to request specific data, promoting efficiency and flexibility in data retrieval.
field
A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.
typeAuthor{
# 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.
typeAuthor{
# id, firstName, and lastName are all fields of the Author type
id:Int!
firstName:String
lastName:String
}
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.
field
A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.
typeAuthor{
# 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:
typeUser{
username:String!@lowerCase
}
field
A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.
typeAuthor{
# id, firstName, and lastName are all fields of the Author type
id:Int!
firstName:String
lastName:String
}
GraphQL
An open-source query language and specification for APIs that enables clients to request specific data, promoting efficiency and flexibility in data retrieval.
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:
typeUser{
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:
typeUser{
username:String!@lowerCase
}
field
A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.
typeAuthor{
# id, firstName, and lastName are all fields of the Author type
id:Int!
firstName:String
lastName:String
}
Rover
Apollo's command-line interface for managing and maintaining graphs with GraphOS.
field
A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.
typeAuthor{
# 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:
typeUser{
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:
typeUser{
username:String!@lowerCase
}
fields
A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.
typeAuthor{
# id, firstName, and lastName are all fields of the Author type
id:Int!
firstName:String
lastName:String
}
GraphQL schema
A GraphQL schema defines the structure and types of data that can be queried or mutated, serving as a contract between the server and clients.
fields
A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.
typeAuthor{
# 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.
typeAuthor{
# id, firstName, and lastName are all fields of the Author type
id:Int!
firstName:String
lastName:String
}
Rover
Apollo's command-line interface for managing and maintaining graphs with GraphOS.
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.
GraphQL
An open-source query language and specification for APIs that enables clients to request specific data, promoting efficiency and flexibility in data retrieval.
operation
A single query, mutation, or subscription that clients send to a GraphQL server to request or manipulate data.
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:
typeUser{
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:
typeUser{
username:String!@lowerCase
}
field
A unit of data that belongs to a type in a schema. Every GraphQL query requests one or more fields.
typeAuthor{
# id, firstName, and lastName are all fields of the Author type
id:Int!
firstName:String
lastName:String
}
operation
A single query, mutation, or subscription that clients send to a GraphQL server to request or manipulate data.
operation
A single query, mutation, or subscription that clients send to a GraphQL server to request or manipulate data.
GraphQL
An open-source query language and specification for APIs that enables clients to request specific data, promoting efficiency and flexibility in data retrieval.
query
A request for specific data from a GraphQL server. Clients define the structure of the response, enabling precise and efficient data retrieval.
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.