Build a GraphQL API on Function Compute + API Gateway
Tags: alibabacloud, graphql, alibaba
Published: 2018-08-11 09:24:33

---
title: Build a GraphQL API on Function Compute + API Gateway
published: true
description: The first step to build GraphQL API on Alibaba Cloud
tags: AlibabaCloud, GraphQL, Alibaba
---

# 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.

```sh
$ 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"}]}}
```

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:

```javascript
Query: "{ hello }"
Return Value: { data: { hello: "world" } }
```

This sample below came from [Official GitHub](https://github.com/graphql/graphql-js).

```javascript
// 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 });
  });
});
```

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"

```javascript
Query: "{ messages { name body } }"
Return value: {"data":{"messages":[{"body":"Hello","name":"asmsuechan"},{"body":"World","name":"suechan"}]}}
```

I defined a type named `message` to get plural `message`.

```javascript
// 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 });
  });
};
```

I saw it works fine by executing `curl`.

```sh
$ 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"}]}}
```

# 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