DEV Community

asmsuechan
asmsuechan

Posted on • Updated on

Build a GraphQL API on Function Compute + API Gateway

What is GraphQL?

GraphQL is a query language for APIs
from: https://graphql.org/

We got a result by throwing POST request to one endpoint.

The curl command below is an example to get messages.

$ curl -H "Content-Type: application/json" -X POST -d '
{
  "query": "{ messages { name body } }"
}
' http://xxxxxxxxxxxxxxxxxx-cn-shanghai.alicloudapi.com/
โ€จ{"data":{"messages":[{"body":"Hello","name":"asmsuechan"},{"body":"World","name":"suechan"}]}}
Enter fullscreen mode Exit fullscreen mode

For more information, please google graphql. I don't go detailed explanations about it in this article.

Minimum Code

First, I wrote the minimum GraphQL code and made it work on Function Compute.

I expected the combination of query and return value below:

Query: "{ hello }"
Return Value: { data: { hello: "world" } }
Enter fullscreen mode Exit fullscreen mode

This sample below came from Official GitHub.

// index.js
const { hook } = require('fc-helper');
const {
  graphql,
  GraphQLSchema,
  GraphQLObjectType,
  GraphQLString
} = require('graphql');

const schema = new GraphQLSchema({
  query: new GraphQLObjectType({
    name: 'RootQueryType',
    fields: {
      hello: {
        type: GraphQLString,
        resolve() {
          return 'world';
        }
      }
    }
  })
});

const query = '{ hello }';

module.exports.handler = (event, context, callback) => {
  graphql(schema, query).then((result) => {
    callback(null, { statusCode: 200, body: result });
  });
});
Enter fullscreen mode Exit fullscreen mode

It's easy. Just exec graphql() in the handler function.

More detailed API

Next, I made the API better. I expected the combination of query and return values below"

Query: "{ messages { name body } }"
Return value: {"data":{"messages":[{"body":"Hello","name":"asmsuechan"},{"body":"World","name":"suechan"}]}}
Enter fullscreen mode Exit fullscreen mode

I defined a type named message to get plural message.

// index.js
const { hook } = require('fc-helper');
const {
  graphql,
  GraphQLSchema,
  GraphQLObjectType,
  GraphQLList,
  GraphQLString
} = require('graphql');
const atob = require('atob');

const messages = [
  {
    name: 'asmsuechan',
    body: 'Hello'
  },
  {
    name: 'suechan',
    body: 'World'
  }
];

const schema = new GraphQLSchema({
  query: new GraphQLObjectType({
    name: 'RootQueryType',
    fields: {
      messages: {
        type: GraphQLList(
          new GraphQLObjectType({
            name: 'message',
            fields: {
              name: { type: GraphQLString },
              body: { type: GraphQLString },
            },
          }),
        ),
        resolve() {
          return messages;
        }
      }
    }
  })
});

module.exports.handler = (event, context, callback) => {
  const request = JSON.parse(event.toString('utf8'))
  const query = JSON.parse(atob(request["body"]))["query"]
  graphql(schema, query).then((result) => {
    callback(null, { statusCode: 200, body: result });
  });
};
Enter fullscreen mode Exit fullscreen mode

I saw it works fine by executing curl.

$ curl -H "Content-Type: application/json" -X POST -d '
{ "query": "{ messages { name body } }"}
'http://xxxxxxxxxxxxxxxxxx-cn-shanghai.alicloudapi.com/

{"data":{"messages":[{"body":"Hello","name":"asmsuechan"},{"body":"World","name":"suechan"}]}}
Enter fullscreen mode Exit fullscreen mode

Conclution

It's very happy to use GraphQL instead of REST API on Function Compute + API Gateway because we can create complex APIs without many API Gateways.

However, it's too fast to run as production environment.

Here's my repository of this article:

https://github.com/asmsuechan/fc_graphql_api

Top comments (0)