SwagQL
Use GraphQL in minutes, leave the REST to us
GraphQL provides a structured approach to fetch and update data. It has several advantages over REST, such as client-driven development, where the client can request any data they need and GraphQL server will determine where to get that data from. It also prevents over-fetching and under-fetching by providing the precise amount of data the client needs.
If you are creating a new API backend, considering GraphQL for all API interaction is practical. But what if you have a REST-based API already available in production? It helps to start developing new client features using a GraphQL interface which relies on your own battle-tested REST APIs. To do that, we have built SwagQL.
SwagQL takes the Swagger (a.k.a. OpenAPI) specification generated/used by a given REST API backend and builds a GraphQL schema in minutes.
The generated schema includes Type definitions, Queries, and Mutations which map to the endpoints represented in the Swagger schema. It also handles the connections between different objects and pagination. If you want to inject authentication checks early in the data fetch cycle, SwagQL provides you a pluggable function for that.
Let’s jump into creating a simple GraphQL server using SwagQL!
Take an example Swagger spec such as the Petstore example at https://petstore.swagger.io/. We will build a GraphQL interface for this backend using a few steps.
Create an npm package
mkdir petstore-graphql
cd petstore-graphql
npm init
Store the spec as petstore.json
curl -o petstore.json https://petstore.swagger.io/v2/swagger.json
Install SwagQL and other packages to run the server
npm i swagql express express-graphql gofer
Generate a GraphQL schema from the downloaded swagger spec
swagql < petstore.json > petstore-graphql.js
Add pagination support by creating a file named array-to-connection.js. For now, we will refer to the default implementation of array-to-connection in SwagQL.
// array-to-connection.js
'use strict';module.exports = require('swagql/array-to-connection.js');
Create a server using Express
// server.js
'use strict';const PORT = 8000;
const express = require('express');
const app = express();app.listen(PORT);
console.log(`Listening on http://localhost:${PORT}`);
Add GraphQL Express to handle the GraphQL requests
// server.js
const graphqlHTTP = require('express-graphql');// before app.listen
app.use('/graphql', graphqlHTTP({
graphiql: true
}));
Add Schema and Context for GraphQL handler. The generated schema exposes a symbol named FETCH which allows us to specify the fetch function of your API client. An API client has the details such as the base url, proxy setup, etc. To provide the fetch function to the schema, we set it as FETCH property of the context. For this example, let’s create an apiClient using the Gofer library.
const { schema, FETCH } = require('./petstore-graphql');
const Gofer = require('gofer');const apiClient = new Gofer()
.with({baseUrl: 'http://petstore.swagger.io/v2'});app.use('/graphql', graphqlHTTP({
schema: schema,
context: { [FETCH]: apiClient.fetch.bind(apiClient) },
graphiql: true
}));
That’s it! Here is the entire server.js
Go ahead and visit http://localhost:8000/graphql to open the GraphiQL interface and try a simple query.
Feel free to try out SwagQL for your Swagger/OpenAPI Schema. Please note that you may have to customize array-to-connection if your REST APIs handle pagination differently than the default implementation.
In certain cases, you may want to check the authentication and authorization of a request before hitting the backend. To facilitate that, SwagQL exposes a Symbol named VERIFY_AUTH_STATUS. You can define a function that checks auth status for a given request and pass it to the schema as context[VERIFY_AUTH_STATUS]. Please find more details in the SwagQL README.
Please report issues at https://github.com/groupon/swagql/issues