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.

tip
Check out the Connectors Mapping Playground to experiment with and troubleshoot mapping expressions. If you learn best with videos and exercises, this interactive course teaches the syntax and methods of the Connectors mapping language.

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:

title="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.

JSON
$args
{
  "filters": [
    { "value": 1 },
    { "value": 2 },
    { "value": 3 }
  ]
}
JSON
Result of $args.filters.value
[1, 2, 3]

Creating objects

For this section, assume that $args contains this JSON object:

JSON
$args
{ "handle": "alice", "email": "alice@example.com" }

When you give a value a name, you create an object containing that value:

GraphQL
Expression
username: $args.handle
JSON
Result
{ "username": "alice" }

You can combine multiple fields to create an object with multiple properties:

GraphQL
Expression
username: $args.handle
email: $args.email
JSON
Result
{
  "username": "alice",
  "email": "alice@example.com"
}

Nested objects

You can create a new object as the property of another object using curly braces ({}):

GraphQL
Expression
user: {
  username: $args.handle
  email: $args.email
}
JSON
Result
{
  "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.

GraphQL
Expression
$args {
  username: $.handle
  email: $.email
}
JSON
Result
{
  "username": "alice",
  "email": "alice@example.com"
}

As shorthand, you can omit $. and refer to the fields only by their names:

GraphQL
Expression
$args {
  username: $.handle
  email: $.email
}
GraphQL
Equivalent expression
$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:

GraphQL
Expression
$args {
  username: handle
  email: email
}
GraphQL
Equivalent expression
$args {
  username: handle
  email
}

You can combine this with the ability to create nested objects by adding back in the user: field name:

GraphQL
Expression
user: $args {
  username: handle
  email
}
JSON
Result
{
  "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:

JSON
$args
{
  "user": {
    "handle": "alice",
    "email": "alice@example.com"
  },
  "company": {
    "name": "Acme",
    "address": "123 Main St"
  }
}

You can select all the data like this:

GraphQL
Expression
$args {
  user {
    username: handle
    email
  }
  organization: company {
    name
    address
  }
}
JSON
Result
{
  "user": {
    "username": "alice",
    "email": "alice@example.com"
  },
  "organization": {
    "name": "Acme",
    "address": "123 Main St"
  }
}
note
Because the 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:

JSON
JSON Response
{
  "id": "1",
  "username": "alice",
  "email": "alice@example.com"
}

You can use this basic selection to select all of a user's fields.

GraphQL
Example selection
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

Feedback

Ask Community