Tutorial

Federating APIs with API Connect Essentials and GraphQL Yoga

Use GraphQL federation in API Connect to combine multiple GraphQL APIs

By

Sam Hill

Archived content

Archive date: 2024-04-02

This content is no longer being updated or maintained. The content is provided “as is.” Given the rapid evolution of technology, some content, steps, or illustrations may have changed.

GraphQL Yoga and the API Connect Essentials (formerly StepZen) product, that's available under API Connect, provide a simple setup experience for creating and federating GraphQL APIs.

One of the unique capabilities of GraphQL is that you can combine multiple GraphQL APIs into a single, unified GraphQL API. This pattern, often called GraphQL Federation, relies on GraphQL's specification that's at the core of every GraphQL API.

In this tutorial, you learn how to federate a GraphQL endpoint with API Connect Essentials and GraphQL Yoga. It describes the similarities and differences between the GraphQL server technologies.

Notice: StepZen was acquired by IBM in 2023 and renamed to API Connect Essentials. Some artifacts still use the StepZen name.

Prerequisites

Users should have experience with building GraphQL APIs.

Estimated time

It should take approximately 10 minutes to complete the tutorial.

Steps

Step 1: Set up a GraphQL Yoga endpoint

Follow the installation instructions in the GraphQL Yoga Quick Start tutorial.

The server and file structure setup of GraphQL Yoga is similar to a front-end Node.js application:

.
├── main.ts
├── tsconfig.json
├── package-lock.json
└── package.json

After you install and set up GraphQL Yoga, two dependencies, graphql-yoga and graphql are installed. If you prefer typescript, modify package.json to reference types and to rely on a tsconfig.json.

{
  "name": "yoga-apic",
  "version": "1.0.0",
  "description": "",
  "scripts": {
    "start": "ts-node main.ts"
  },
  "dependencies": {
    "graphql": "^16.8.1",
    "graphql-yoga": "^5.0.0"
  },
  "devDependencies": {
    "@types/node": "16.11.7",
    "ts-node": "10.8.1",
    "ts-node-dev": "1.1.8",
    "typescript": "4.7.4"
  }
}

tsconfig.json

{
  "compilerOptions": {
    "target": "es2016",                                  /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
    "module": "commonjs",                                /* Specify what module code is generated. */
    "skipLibCheck": true                                 /* Skip type checking all .d.ts files. */
  }
}

Now that the dependencies are set up, you can generate a simple query with graphql-yoga in the main.ts file.

import { createServer } from 'node:http'
import { createSchema, createYoga } from 'graphql-yoga'

const yoga = createYoga({
  schema: createSchema({
    typeDefs: /* GraphQL */ `
      type Query {
        hello: String
      }
    `,
    resolvers: {
      Query: {
        hello: () => 'Hello from Yoga!'
      }
    }
  })
})

const server = createServer(yoga)

server.listen(4000, () => {
  console.info('Server is running on http://localhost:4000/graphql')
})

By running the npm run start command, a simple query is created, which you can explore by using this endpoint: http://localhost:4000/graphql

Query GraphQL Yoga

Step 2. Deploy an API Connect Essentials GraphQL endpoint

To deploy a GraphQL endpoint with API Connect Essentials, the file structure is not similar to the Node.js application we deployed in the previous step. Instead, the entier API is described inside GraphQL schema files:

.
├── rick.graphql
└── index.graphql

In the GraphQL schema that we are using in this tutorial, a @graphql directive connects to a public GraphQL endpoint. This API has information about the television show "Rick and Morty", and has details about its episodes and characters.

You can use the stepzen import graphql command to import and query the entire schema from a GraphQL endpoint. To keep this tutorial shorter, we are going to be querying the only list of characters from this endpoint.

type Name {
  name: String
}

type Characters {
  results: [Name]
}

type Query {
  characters: Characters
    @graphql(
      endpoint: "https://rickandmortyapi.com/graphql"
    )
}

From the root folder where you created these .graphql files, run the stepzen deploy --endpoint api/blog command and a new endpoint is deployed for you. The flag --endpoint is used here to set a name for the endpoint.

API Connect Essentials dashboard AWS

Step 3. Federate the API Connect Essentials endpoint with GraphQL Yoga

Return to the GraphQL Yoga application and replace the basic hello query with our characters query from API Connect Essentials.

import { createServer } from 'node:http'
import { createSchema, createYoga } from 'graphql-yoga'

const constants = {
  url: 'https://dev0008.us-east-a.ibm.steprz.net/api/blog/__graphql',
  apikey: 'xxxx'
}

const yoga = createYoga({
  schema: createSchema({
    typeDefs: /* GraphQL */ `
      type Name {
        name: String
      }
      type Characters {
        results: [Name]
      }
      type Query {
        characters: Characters
      }
    `,
    resolvers: {
      Query: {
        characters: async (_, {}, context, info) => {
            try {
              const query = context['params']['query']
              const request = await fetch(constants.url, {
                method: 'POST',
                headers: {
                  'Content-Type': 'application/json',
                  'Authorization': `Apikey ${constants.apikey}`
                },
                body: JSON.stringify({
                  query: context['params']['query'],
                  variables: {},
                }),
              })
                .then(res => res.json())
                .then(data => {
                  return data
                })
                .catch(error => {
                  return error
                })

                return request.data.characters
            } catch (e) {
              return e
              // console.log('error finding the query name from the endpoint provided')
            }
        },
      }
    }
  })
})

const server = createServer(yoga)

server.listen(4000, () => {
  console.info('Server is running on http://localhost:4000/graphql')
})

The same GraphQL schema, excluding the @graphql directive, is going to be used as the typeDefs for GraphQL Yoga.

typeDefs: /* GraphQL */ `
  type Name {
    name: String
  }
  type Characters {
    results: [Name]
  }
  type Query {
    characters: Characters
  }
`,

To request data from the API Connect Essentials GraphQL endpoint https://ACCOUNT.us-east-a.ibm.steprz.net/api/blog/__graphql, be sure to change ACCOUNT to your account name and paste the following frontend JavaScript code snippet:

const request = await fetch(constants.url, {})

Find the apikey to query your API Connect Essentials GraphQL endpoint with the stepzen whoami --apikey command, and then paste it into the constants object.

const query = context['params']['query']
const request = await fetch(constants.url, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Apikey ${constants.apikey}`
  },
  body: JSON.stringify({
    query: query,
    variables: {},
  }),å
})

The query is being passed as context['params']['query']. This query is taking the exact query that is made to the GraphQL Yoga server and running it in the API Connect Essentials GraphQL API.

const query = context['params']['query']

Run the npm run start command to explore the GraphQL Yoga endpoint at http://localhost:4000/graphql.

Characters Query in GraphQL Yoga

Summary and next steps

In this tutorial, you learned how to federate a GraphQL endpoint with two different GraphQL server technologies to query Rick and Morty data.

First, we've set up a GraphQL Yoga endpoint and then federated a new API Connect GraphQL endpoint. But it can also be done in the other order by querying GraphQL Yoga into an API Connect Essentials @graphql directive. We went in this direction because API Connect Essentials automatically deploys a GraphQL endpoint to the cloud. Being an open source technology, GraphQL Yoga does not deploy the endpoint to the cloud by default.

We'd love to hear what you're building with GraphQL and API Connect Essentials. Join our Discord Community and let us know.