Build and Deploy a Simple Apollo GraphQL Federated Schema Using AWS EKS (Kubernetes)-Pt.1
This tutorial is part 1 of this series.
- Part 1: Building a simple GraphQL federated schema
- Part 2: REST API Data fetching with REST Data Source
- Part 3: Deploy using AWS EKS Kubernetes & AWS Fargate
Why use Apollo federation?
As a developer that has implemented a data graph using GraphQL and ApolloServer you may be faced with the question of how to manage an ever-growing data graph and the services that support it in an efficient and scalable way while achieving a true separation of concerns.
One option available is to utilise Apollo schema federation, which uses a Gateway to compose a single data graph which acts as a unified interface for querying consolidated data from all of your services. Furthermore, the Apollo graph manager will help you manage, validate, and secure your organisation’s data graph from a single location accessible by all developers.
Example Federated schema architecture:
This allows us to achieve a true separation of concerns with each service being responsible for resolving the data represented in its data graph implementation.
What we’ll be building?
A simple application that displays a user’s personal cryptocurrency wallet holdings and balance, along with user data and currency information. We’ll connect to the Coin Marketcap REST API to query the crypto data in part 2.
1. User Service
Let’s get started by building the services as they’ll need to be up and running in order for our gateway to discover them and compose our data graph.
Open up your terminal and clone the starter project
git clone https://github.com/maisonam/apollo-federation-starter.git && cd apollo-federation-starter
Open the services/user-api directory and install dependencies
npm install
Then run
npm install apollo-server@2.13.1 @apollo/federation@0.16.0
Open the /user-api/index.js file in your editor, which will be used as the entry point into this service and add the following server definition
Next we’ll define our user schema by first creating the following folder and file in the root of the /user-api directory
mkdir schema && cd schema && touch index.js
Open user-api/schema/index.js in your editor and add the following schema definition:
Now that we have our schema for our data structure, we’ll define the data to be returned by creating some example user data. From the root of the /user-api directory, type the following:
mkdir models && cd models && touch index.js
Open user-api/models/index.js in your editor and add the following example data:
Next we’ll define our user resolver by first creating the user resolver file. From (the root) of the /user-api directory, type the following:
mkdir resolvers && cd resolvers && touch index.js
Open resolvers/index.js in your editor and add the following resolver definition:
From the root of the /user-api directory, you should now be able to start the graphql playground and query a user by id:
npm run start
Query a user by visiting http://localhost:5001 in your browser and pasting the following query and query variables:
You should receive the details of the user with “id” 1. We can now stop this service as we’ll be running it in a different way later. In the terminal, stop the user service and navigate to the services/wallet-api directory.
2. Wallet service
We’ll follow very similar steps for defining the wallet service.
Let’s install all dependencies
npm install
Then run
npm install apollo-server@2.13.1 @apollo/federation@0.16.0
Open the /wallet api/index.js file in your editor, which will be used as the entry point into this service and add the following server definition:
Next we’ll define our wallet schema by first creating the following folder and file from the root of the /wallet-api directory
mkdir schema && cd schema && touch index.js
Open /wallet-api/schema/index.js in your editor and add the following schema definition:
Then we’ll create some example user wallet data. From the root of /wallet-api directory:
mkdir models && cd models && touch index.js
Model wallet data for /wallet-ap/models/index.js:
Finally let’s create the wallet resolver file. From the root of the /wallet-api directory:
mkdir resolvers && cd resolvers && touch index.js
Open /wallet-api/resolvers/index.js in your editor and add the following resolvers definition:
From the root of the /wallet-api directory, you should now be able to start the GraphQL playground and query all wallets:
Start the api:
npm run start
Query all wallets by visiting http://localhost:5002 in your browser and pasting the following query:
This should return an array of all wallets. You may have noticed that our schema has given this service the ability to query a wallet owners information via the “User” type, but as the wallet service is only available to resolve data about Wallets and the User service is no longer running, we’ll leave it up to our Gateway which we’ll define next to bring our services together.
We can now stop this service as we’ll be running it in a different way.
Before moving on, let’s take a moment to reflect on what we’ve achieved so far. We have implemented two services that allow us to have a true separation of concerns, with the Users services defining the user schema and how user data is resolved for this service and all other services implementing user data, and likewise for the Wallet service. Now that our services are working and returning data we can create our gateway to bring all of our services under one roof and query them all from a single endpoint.
4. The gateway
From the root directory /apollo-federation-starter, install the following dependencies by running:
npm run install
Then run
npm install @apollo/gateway@0.13.2 apollo-server@2.11.0 graphql@14.6.0 dotenv@8.2.0
Open the /apollo-federation-starter/gateway.js file in your editor which will be used as the entry point into the gateway and add the following server definition:
Let’s start the services in the terminal:
npm run start-services
Now let’s start the gateway in a new terminal window (CMD+T):
npm run start-gateway
You should now be able to query all data from your services in your Apollo gateway. Open the GraphQL playground by visiting http://localhost:4000 and paste in the following queries:
The following query will return a single wallet with the owner’s (user) data resolved from the user-api service… 🥳👨💻🔮
To query a user:
That’s it for part 1. As a challenge, why not try extending the User service to return a user’s wallet info when a user is queried?
In part 2 we’ll learn how to restrict access to individual services unless they originate from the gateway and how to resolve data from REST APIs.