Mapping Language Overview
Convert data to and from GraphQL types using the Apollo Connectors mapping language
This overview describes the Apollo Connectors mapping language. You use the mapping language anywhere data needs to be transformed from one form to another. This includes building URIs and headers when making requests, constructing request bodies, and mapping response data to GraphQL schema.
The basics
The mapping language uses a declarative approach to transforming data from one shape to another. Unlike traditional programming languages, it doesn't have state or loops. Since the mapping language borrows heavily from the GraphQL query language, some concepts like the alias syntax and array handling might look familiar.
Fields and paths
The most basic mapping expression selects a value from a path.
For example, a URI path might include the expression $args.id
.
This expression means, "Use the id
field of the $args
variable."
For example:
type Query {
product(id: ID!): Product
@connect(
source: "ecomm"
http: { GET: "/products/{$args.id}" }
selection: "id name description"
)
}
When applied to an array, the result of a path is also an array.
For example, if $args.filters
is an array of objects, $args.filters.value
is an array of the value
property of each object.
{
"filters": [
{ "value": 1 },
{ "value": 2 },
{ "value": 3 }
]
}
[1, 2, 3]
Creating objects
For this section, assume that $args
contains this JSON object:
{ "handle": "alice", "email": "alice@example.com" }
When you give a value a name, you create an object containing that value:
username: $args.handle
{ "username": "alice" }
You can combine multiple fields to create an object with multiple properties:
username: $args.handle
email: $args.email
{
"username": "alice",
"email": "alice@example.com"
}
Nested objects
You can create a new object as the property of another object using curly braces ({}
):
user: {
username: $args.handle
email: $args.email
}
{
"user": {
"username": "alice",
"email": "alice@example.com"
}
}
Subselections
If multiple properties from an object come from another object, you can use a subselection to avoid repeating the object name. The $
variable in the curly braces refers to the selected object—whatever comes directly before the {
. In the following example, that's $args
.
$args {
username: $.handle
email: $.email
}
{
"username": "alice",
"email": "alice@example.com"
}
As shorthand, you can omit $.
and refer to the fields only by their names:
$args {
username: $.handle
email: $.email
}
$args {
username: handle
email: email
}
When the name of the new field matches the name of the source, you can also omit the left-hand side:
$args {
username: handle
email: email
}
$args {
username: handle
email
}
You can combine this with the ability to create nested objects by adding back in the user:
field name:
user: $args {
username: handle
email
}
{
"user": {
"username": "alice",
"email": "alice@example.com"
}
}
Multiple levels
For more complex inputs, you can use multiple subselections to achieve the desired result without repetition. Suppose $args
looks like this:
{
"user": {
"handle": "alice",
"email": "alice@example.com"
},
"company": {
"name": "Acme",
"address": "123 Main St"
}
}
You can select all the data like this:
$args {
user {
username: handle
email
}
organization: company {
name
address
}
}
{
"user": {
"username": "alice",
"email": "alice@example.com"
},
"organization": {
"name": "Acme",
"address": "123 Main St"
}
}
user
property being creating comes from the parent's property of the same name, you can use the shorthand
syntax when creating the object.Special case for selection
For the @connect
directive's selection
argument only, a top-level $
refers to the root of the response body from the source API.
This means you can select basic GraphQL fields succinctly.
For example, given this JSON response:
{
"id": "1",
"username": "alice",
"email": "alice@example.com"
}
You can use this basic selection
to select all of a user's fields.
type Query {
user(id: ID!): User
@connect(
http: { GET: "https://api.example.com/users/{$args.id}" }
selection: "id username email"
)
}
type User {
id: ID!
username: String!
email: String!
}
Since the REST endpoint returns username
and email
in its
response, you can map them directly to fields of the same name in the GraphQL schema using the shorthand that omits the $
.
Additional resources
See additional pages for variables, methods, and common mapping patterns like arrays, enums, and literal values.
Refer to the guide on Mapping Response Fields for examples of common selection mappings.