A Serverless Blog leveraging GraphQL to offer a REST API with only 1 endpoint using Serverless v0.5
JavaScript
Latest commit 54b60d0 Dec 7, 2016 @DavidWells DavidWells committed on GitHub Update README.md

README.md

Serverless GraphQL Blog AWS Lambda API Gateway

serverless

Please note this project uses Serverless version 0.5

serverless-graphql-blog

This Serverless Framework Project creates a REST API for a basic blog structure, including Posts, Authors and Comments utilizing GraphQL and DynamoDB for persistent storage. What's unique about this implementation is the entire REST API consists of only 1 endpoint.

Note: This project automatically creates 3 DynamoDB tables upon serverless project install. They are defined in s-project.json.

Enjoy,
Kevin Old (Twitter)

Install & Deploy

Make sure you have the most recent version of the Serverless Framework (0.5.x and higher) and you are using NodeV4 or greater.

npm install serverless -g

Install this Serverless Project:

serverless project install serverless-graphql-blog

Install (top level) npm dependencies

npm install

View project summary:

serverless dash summary

Deploy the project's Function and Endpoint:

serverless dash deploy

Serverless GraphQL Blog Video Walkthrough

Querying with GraphiQL

The graphql-js endpoint provided in this Serverless Project is compatible with GraphiQL, a query visualization tool used with graphql-js.

Usage with GraphiQL.app (an Electron wrapper around GraphiQL) is recommended and is shown below:

GraphiQL.app demo

Sample GraphQL queries

List of author names

curl -XPOST -d '{"query": "{ authors { name } }"}' <endpoint>/dev/blog/graphql

Results

{
  "data":{
    "authors":[
      {"name":"Kevin"}
    ]
  }
}

List of posts with id and title

curl -XPOST -d '{"query": "{ posts { id, title } }"}' <endpoint>/dev/blog/graphql

Results

{
  "data": {
    "posts": [
      { "id":"1",
        "title":"First Post Title"
      }
    ]
  }
}

List of posts with id, title and nested author name

curl -XPOST -d '{"query": "{ posts { id, title, author { name } } }"}' <endpoint>/dev/blog/graphql

Results

{
  "data": {
    "posts": [
      { "id":"1",
        "title":"First Post Title",
        "author":{
          "name":"Kevin"
        }
      }
    ]
  }
}

List of posts with post, author and comments information (for a Post with no comments, i.e. comments:[])

curl -XPOST -d '{"query": "{ posts { id, title, author { id, name }, comments { id, content, author { name } } } }"}' <endpoint>/dev/blog/graphql

Results

{
  "data":{
    "posts":[
    {
      "id":"1",
        "title":"First Post Title",
        "author":{
          "id":"1",
          "name":"Kevin"
        },
        "comments":[]
    }
    ]
  }
}

Sample GraphQL Mutations

Create Post

curl -XPOST -d '{"query": "mutation createNewPost { post: createPost (id: \"5\", title: \"Fifth post!\", bodyContent: \"Test content\", author: \"1\") { id, title } }"}' <endpoint>/dev/blog/graphql

Results

{
  "data":{
    "post":{
      "id":"5",
      "title":"Fifth post!"
    }
  }
}

Mutation Validation

Validations defined using graphql-custom-types in blog/lib/schema.js

curl -XPOST -d '{"query": "mutation createNewPost { post: createPost (id: \"8\", title: \"123456789\", bodyContent: \"Test content 5\") { id, title } }"}' <endpoint>/dev/blog/graphql

Results

{
  "errors":[
  {
    "message":"Query error: String not long enough"}
  ]
}

Introspection Query

curl -XPOST -d '{"query": "{__schema { queryType { name, fields { name, description} }}}"}' <endpoint>/dev/blog/graphql

Returns:

{
  "data":{
    "__schema":{
      "queryType":{
        "name":"BlogSchema",
          "fields":[
          {
            "name":"posts",
            "description":"List of posts in the blog"
          },
          {
            "name":"authors",
            "description":"List of Authors"
          },
          {
            "name":"author",
            "description":"Get Author by id"
          }
        ]
      }
    }
  }
}