Running a GraphQL endpoint with Serverless
Tags: graphql, tutorial, serverless, node
Published: 2023-01-30 09:07:54

**GraphQL?**
In case you are not familiar with it, GraphQL is a data query language created by Facebook. GraphQL allows the client to select ad-hoc data. This differentiates it from REST API’s that expose pre-set data structures. [More here](https://dev.to/grigorkh/what-is-graphql-4n9j)

**Serverless?**
Serverless pattern encourages development focus on well-defined units of business logic, without premature optimization decisions related to how this logic is deployed or scaled.

### Setting up the Serverless Framework ###

Before we start, make sure you have Node.js and npm installed on your machine. You can check this by running the following commands:
```bash
node -v
npm -v
```
Next, install the Serverless Framework globally:
```bash
npm install -g serverless
```
Now that we have the Serverless Framework installed, let’s create a new Serverless project:
```bash
serverless create --template aws-nodejs --path graphql-serverless
```
This will create a new Serverless project using the AWS Node.js template in a directory named graphql-serverless.

### Installing the Required Libraries

To run a GraphQL endpoint, we need to install the following libraries:
```bash
npm install apollo-server-lambda graphql
```
`apollo-server-lambda` is a library that makes it easy to run an Apollo GraphQL server on AWS Lambda. `graphql` is the library that provides the GraphQL implementation.

### Writing the GraphQL Schema

The next step is to write the GraphQL schema. This schema defines the types and the operations that can be performed on these types.

Create a `schema.js` file in the `graphql-serverless` directory with the following code:
```js
const { gql } = require("apollo-server-lambda");

const typeDefs = gql`
  type Query {
    hello: String
  }
`;

module.exports = typeDefs;
```

This is a simple schema that defines a single operation hello that returns a string.

### Writing the GraphQL Resolvers

Next, we need to write the resolvers. Resolvers are the functions that implement the operations defined in the schema.

Create a `resolvers.js` file in the `graphql-serverless` directory with the following code:
```js
const resolvers = {
  Query: {
    hello: (_, __, context) => {
      return "Hello, Serverless!";
    },
  },
};

module.exports = resolvers;
```

This resolver implements the hello operation from the schema and returns the string `"Hello, Serverless!"`.

### Setting up the Apollo Server

Finally, we need to set up the Apollo Server.

Create a `handler.js` file in the `graphql-serverless` directory with the following code:
```js
const { ApolloServer } = require("apollo-server-lambda");
const typeDefs = require("./schema");
const resolvers = require("./resolvers");

const server = new ApolloServer({
  typeDefs,
  resolvers,
});

exports.graphqlHandler = server.createHandler();
```

This sets up the Apollo Server using the typeDefs and resolvers from the previous sections.

### Configuring the Serverless Function

Now that we have the GraphQL endpoint set up, we need to configure the Serverless function to run it.

Update the `serverless.yml` file in the `graphql-serverless` directory with the following code:

```yaml
service: graphql-serverless
provider:
  name: aws
  runtime: nodejs18.x

functions:
  graphql:
    handler: handler.graphqlHandler
    events:
      - http:
          path: graphql
          method: post

plugins:
 - serverless-apollo-middleware
```
This configures a single Serverless function named `graphql` that will be triggered by a HTTP POST request to the `/graphql` endpoint. It also includes the `serverless-apollo-middleware` plugin, which is required for the Apollo Server to work on AWS Lambda.

### Deploying the Serverless Function

The final step is to deploy the Serverless function to AWS. Run the following command in the `graphql-serverless` directory:
```bash
serverless deploy
```

This will deploy the function to AWS and return the URL of the GraphQL endpoint.

### Testing the GraphQL Endpoint

You can use a tool like [Insomnia](https://insomnia.rest/) or [Postman](https://www.postman.com/) to test the GraphQL endpoint.

Create a new POST request to the URL of the GraphQL endpoint with the following query in the request body:
```graphql
query {
  hello
}
```
Send the request and you should receive the following response:
```json
{
  "data": {
    "hello": "Hello, Serverless!"
  }
}
```

### Continuous Integration and Deployment (CI/CD) using GitHub Actions

To automate the deployment process, we can set up a CI/CD pipeline using GitHub Actions. GitHub Actions allows you to automate your workflow by creating custom actions that run whenever a specific event occurs in your GitHub repository.

Create a new file named `.github/workflows/deploy.yml` in your GitHub repository with the following code:
```yaml
name: Deploy

on:
  push:
    branches:
      - main

env:
  AWS_REGION: us-east-1
  AWS_PROFILE: default

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ${{ env.AWS_REGION }}

      - name: Deploy to AWS
        uses: anothrNick/serverless-action@v1
        with:
          command: deploy
```
This action is triggered whenever a push is made to the main branch of the GitHub repository. It uses the `anothrNick/serverless-action` action to deploy the Serverless function to AWS.

Make sure to replace `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` in the code above with the actual values from your AWS account. You can store these values as secrets in your GitHub repository.

### Conclusion

In this article, we showed how to run a GraphQL endpoint with Serverless on AWS Lambda. We covered the basics of setting up an Apollo Server and deploying it as a Serverless function. We also showed how to automate the deployment process using GitHub Actions, allowing for a seamless CI/CD pipeline.

By using Serverless, you can take advantage of the scalability and cost-effectiveness of AWS Lambda while keeping the development process simple and streamlined. The combination of GraphQL and Serverless provides a powerful platform for building and deploying modern web applications.

With the code and steps outlined in this article, you should be able to get started with running a GraphQL endpoint with Serverless and continue building upon this foundation for your own projects.