Your first Gateway with Mesh
Mesh being installed, we can now build our first GraphQL Gateway.
All the documentation tutorials and guides rely on the "Books", "Authors" and "Stores" example APIs, available in a dedicated repository: graphql-mesh-docs-first-gateway:
- Books API (REST API)
GET /booksGET /books/:idGET /categories
- Authors API (gRPC API)
GetAuthorListAuthors
- Stores (GraphQL API)
storesQuerybookSells(storeId: ID!)Query
Our goal is to build a Unified GraphQL Schema through a Mesh Gateway that incorporates our 3 example services as follows:
In this tutorial, we will first start by creating a Mesh configuration that incorporates the Books REST API, as follows:
Creating the complete Mesh Gateway that combines "Books", "Authors", and "Stores" APIs in a unified Schema will be covered in the "Setup a Gateway with many Sources" guide.
Add the Books REST API to our GraphQL Gateway
1. A closer look at our Books REST API
To add the Books API as a Source of our GraphQL Mesh configuration, we will need to get the API's definition.
Depending on the API type, many definition types will be available; for example, REST API tends to be described using Open API/Swagger.
Open API is a standard based on JSON Schema (JSON-based files standard) to describe APIs.
Our Books REST API provides an Open API definition file: packages/books-service/openapi3-definition.json.
The openapi3-definition.json file describes the available endpoints along with their arguments and responses shape:
GET /booksGET /books/:idGET /categories
We now established that our Books API will require the openapi Mesh Handler with the @graphql-mesh/openapi package.
2. Creating our Mesh configuration file
Let's go to the packages/single-source/ where the following dependencies are installed:
graphqlis a required peer dependency of GraphQL Mesh@graphql-mesh/cliprovides everything to parse the configuration, execute the Handlers, Transforms and serve the API@graphql-mesh/openapiis the Handler of the "Books" Source
The .meshrc.yaml configuration file contains the following content:
sources:
- name: Books
handler:
openapi:
baseUrl: http://localhost:3002/
source: ../books-service/openapi3-definition.jsonThe configuration is straightforward; we define a Source called "Books" that is configured with the openapi Handler.
By providing the source document path, Mesh will be able to translate the OpenAPI JSON definition to a GraphQL Schema.
Let's first start our Books API and our GraphQL Gateway by running at the root of the project:
yarn start-single-sourceAnd open your favorite web browser at http://0.0.0.0:4000
As expected, Mesh translated the Books REST API to a GraphQL Schema, using the following rules:
- a
GET /api/helloWorldendpoint becomes a Query similar to:helloWorld(): String! - a
POST /api/sayHelloAllendpoint becomes a Mutation similar to:sayHelloAll(input: [SayHelloAllInput]): String PUTandDELETEendpoints are also translated to GraphQL Mutations.
This gives us the following Books GraphQL Schema:
You can try out the following Query:
{
books {
authorId
categorieId
id
title
}
}3. Shaping the Unified Schema
We might not want to expose all those Queries in our Unified Schema.
Let's say that we want to remove the book(id: ID!) Query and rename the categories Query to booksCategories.
To achieve such a final Schema design, we will leverage Transforms.
Remove the book(id: ID!) Query
We will install and configure the filterSchema Transform to remove a Query from the Unified Schema.
Back to the packages/single-source/ folder, you will find the following package installed: @graphql-mesh/transform-filter-schema.
And update our .meshrc.yaml as follows:
sources:
- name: Books
handler:
openapi:
baseUrl: http://localhost:3002/
source: ../books-service/openapi3-definition.json
transforms:
- filterSchema:
filters:
- Query.!bookWe added a transforms key at the root of the configuration.
transforms value is an array of named transforms, ex: filterSchema.
filterSchema takes a filters option that accepts an array of filter rules.
By adding Query.!book, we instruct Mesh to remove the book(…) Query.
More information on the filterSchema Transform on its dedicated documentation page.
Rename the categories(…) Query to booksCategories(…)
Finally, let's rename our categories(…) Query to booksCategories(…) by using the rename Transform.
Again in the packages/single-source/ folder, you will find the following package installed: @graphql-mesh/transform-rename.
And update our .meshrc.yaml as follows:
sources:
- name: Books
handler:
openapi:
baseUrl: http://localhost:3002/
source: ../books-service/openapi3-definition.json
transforms:
- filterSchema:
filters:
- Query.!book
- rename:
renames:
- from:
type: Query
field: categories
to:
type: Query
field: booksCategoriesrename takes a renames option that accepts an array of from/to pairs.
Here, we indicate that Query.categories should be renamed Query.booksCategories.
More information on the rename Transform on its dedicated documentation page.
Our final Unified Schema is now ready to be used:
The power of GraphQL Mesh, on top of providing an extensive range of Handlers, is to empower us to create well-designed GraphQL Schema using Transforms.
Keep in mind that a good GraphQL Schema design should:
- provides useful queries (not expose unnecessary ones)
- simplify the usage by providing the proper abstractions (ex: proper naming and hierarchy)
- provide specialized mutations that represent specific behaviors instead of CRUD mutations directly linked to an underlying data-schema
Our GraphQL Gateway API is ready!
Congratulations! Our Books REST API is now accessible through our Mesh GraphQL Gateway a comprehensive and tailored Schema design.
You can now start again and play with the GraphQL Schema by running:
yarn start-single-sourceAnd open your favorite web browser at http://0.0.0.0:4000 and try the following Query:
{
books {
id
title
categorieId
}
booksCategories {
id
name
}
}Going further
You are now familiar with Mesh's concepts of Sources, Handlers, Transforms, and Unified Schema 🚀.
Let's finish our Gateway in the "Combine multiple Sources" guide.