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 /books
GET /books/:id
GET /categories
- Authors API (gRPC API)
GetAuthor
ListAuthors
- Stores (GraphQL API)
stores
QuerybookSells(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 in the following URL:
http://localhost:3002/openapi.json
.
The openapi.json
file describes the available endpoints along with their arguments and responses
shape associated with a noperation ID:
GET /books
(ID:AppController_books
)GET /books/:id
(ID:AppController_book
)GET /categories
(ID:AppController_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:
graphql
is a required peer dependency of GraphQL Mesh@graphql-mesh/cli
provides everything to parse the configuration, execute the Handlers, Transforms and serve the API@graphql-mesh/openapi
is the Handler of the "Books" Source
The .meshrc.yaml
configuration file contains the following content:
sources:
- name: Books
handler:
openapi:
source: http://localhost:3002/openapi.json
The 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-source
And 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/helloWorld
endpoint becomes a Query similar to:helloWorld(): String!
- a
POST /api/sayHelloAll
endpoint becomes a Mutation similar to:sayHelloAll(input: [SayHelloAllInput]): String
PUT
andDELETE
endpoints are also translated to GraphQL Mutations.
This gives us the following Books GraphQL Schema:
You can try out the following Query:
{
AppController_books {
authorId
categoryId
id
title
}
}
3. Shaping the Unified Schema
We might not want to expose all those Queries in our Unified Schema. In particular, those Queries
are prefixed with AppController_
which is not very user-friendly.
Let's say that we want to:
- remove the
AppController_
prefix on each Query - remove the
book(id: ID!)
Query - rename the
categories
Query tobooksCategories
.
To achieve such a final Schema design, we will leverage Transforms.
Remove the AppController_
prefix
We will start by cleaning up those ugly Query names by removing their prefix.
Let's install the rename
Transform to rename the Query fields. Loocking at the
packages/single-source/
folder, you will find the following package installed: @graphql-mesh/transform-rename
.
We can update our
.meshrc.yaml
as follow:
sources:
- name: Books
handler:
openapi:
source: http://localhost:3002/openapi.json
transforms:
- rename:
renames:
- from:
type: Query
field: AppController_(.*)
to:
type: Query
field: $1
useRegExpForFields: true
We added a transforms
key at the root of the configuration.
transforms
value is an array of named transforms, ex: rename
.
rename
takes a renames
option that accepts an array of from
/to
pairs. Here, we are using a
regexp to capture the end of the Query name, ignoring the AppController_
prefix.
More information on the rename
Transform on
its dedicated documentation page.
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:
source: http://localhost:3002/openapi.json
transforms:
- rename:
renames:
- from:
type: Query
field: AppController_(.*)
to:
type: Query
field: $1
useRegExpForFields: true
- filterSchema:
filters:
- Query.!book
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.
And update our
.meshrc.yaml
as follows:
sources:
- name: Books
handler:
openapi:
source: http://localhost:3002/openapi.json
transforms:
- rename:
renames:
- from:
type: Query
field: AppController_(.*)
to:
type: Query
field: $1
useRegExpForFields: true
- filterSchema:
filters:
- Query.!book
- rename:
renames:
- from:
type: Query
field: categories
to:
type: Query
field: booksCategories
Our final Unified Schema
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-source
And open your favorite web browser at http://0.0.0.0:4000 and try the following Query:
{
books {
id
title
categoryId
}
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.