serverless / serverless-graphql

Serverless GraphQL Examples for AWS AppSync and Apollo
https://www.serverless.com
MIT License
2.72k stars 364 forks source link

Build Status

Introduction

Part 1: Running a scalable & reliable GraphQL endpoint with Serverless
Part 2: AppSync Backend: AWS Managed GraphQL Service
Part 3: AppSync Frontend: AWS Managed GraphQL Service

Serverless GraphQL

This starter kit is an opinionated set of tools combined to help you get started building a Serverless application with a GraphQL endpoint and deploy them to production in minutes.

This example uses the following technologies:

System Architecture

serverless application architecture v2

Quick Setup

You need to have Node 6 or higher installed.

npm install -g serverless
npm install -g yarn
npm install -g netlify-cli

Install Dependencies.

yarn install

Feature Support in this repository

feature-support

Quick Start (Serverless Offline)

Please note: AWS CLI is required to be installed on your system

  1. Select Backend
  1. Start FrontEnd (Apollo Client or Appsync Client)

Also, please make sure GraphQL endpoint is configured correctly in config/security.env.local to run client on local.

  1. Start GraphiQL

    http://localhost:4000/graphiql
  2. Start GraphQL Playground (GraphiQL replacement - coming soon)

    http://localhost:4000/playground

    rest-api and dynamodb backends route GET and POST to the same /graphql endpoint handler

    http://localhost:4000/graphql
  3. Sample Query for GraphiQL, Playground or GraphQL

    {
    getUserInfo(handle: "Madalyn61") {
    name
    tweets {
      items {
        retweeted
        retweet_count
        favorited
        tweet
      }
    }
    topTweet {
      retweeted
      retweet_count
      favorited
    }
    }
    }

If you've followed me this far, DynamoDB will now be available and running on your local machine at http://localhost:8000/shell:

!Live Example

Setup for Production (Deploy resources to AWS)

Configure your AWS keys. Here you can find a 2min walkthrough how to do retrieve the keys.

sls config credentials --provider aws --key <your_aws_access_key> --secret <your_aws_secret_key>

!Live Example

You need to make sure you have access to your deployed lambda functions.

  1. Select Backend

Note Please make sure latest serverless package is installed npm install -g serverless@latest

To use aws appsync you will need to create cognito user pool to authenticate the API Reference

- AWS DynamoDB
    cd app-backend/appsync/dynamodb
    yarn deploy-prod
    yarn deploy-appsync

- AWS ElasticSearch

    cd app-backend/appsync/dynamo-elasticsearch-lambda
    yarn deploy-prod
    yarn deploy-appsync

- AWS Lambda

    cd app-backend/appsync/lambda
    yarn deploy-prod
    yarn deploy-appsync
  1. Config: Get your /graphql POST endpoint as shown below and use it in config/security.env.prod NOTE Please remove all quotes and <> and place only your POST endpoint url otherwise you will get 405 method not allowed error on POST to your endpoint

deploy feedback

  1. Select Frontend (apollo-client or appsync-client)

Example: Appsync Backend Integration

type Mutation {
    # Create a tweet for a user
    # consumer keys and tokens are not required for dynamo integration
    createTweet(
        tweet: String!,
        consumer_key: String,
        consumer_secret: String,
        access_token_key: String,
        access_token_secret: String,
        created_at: String!
    ): Tweet!

    # Delete User Tweet
    deleteTweet(
        tweet_id: String!,
        consumer_key: String,
        consumer_secret: String,
        access_token_key: String,
        access_token_secret: String
    ): Tweet!

    # Retweet existing Tweet
    reTweet(
        tweet_id: String!,
        consumer_key: String,
        consumer_secret: String,
        access_token_key: String,
        access_token_secret: String
    ): Tweet!

    # Update existing Tweet
    updateTweet(tweet_id: String!, tweet: String!): Tweet!

    # Create user info is available in dynamo integration
    updateUserInfo(
        location: String!,
        description: String!,
        name: String!,
        followers_count: Int!,
        friends_count: Int!,
        favourites_count: Int!,
        followers: [String!]!
    ): User!
}

type Query {
    meInfo(consumer_key: String, consumer_secret: String): User!
    getUserInfo(handle: String!, consumer_key: String, consumer_secret: String): User!

    # search functionality is available in elasticsearch integration
    searchAllTweetsByKeyword(keyword: String!): TweetConnection
}

type Subscription {
    addTweet: Tweet
        @aws_subscribe(mutations: ["createTweet"])
}

type Tweet {
    tweet_id: String!
    tweet: String!
    retweeted: Boolean
    retweet_count: Int
    favorited: Boolean
    created_at: String!
}

type TweetConnection {
    items: [Tweet!]!
    nextToken: String
}

type User {
    name: String!
    handle: String!
    location: String!
    description: String!
    followers_count: Int!
    friends_count: Int!
    favourites_count: Int!
    followers: [String!]!
    topTweet: Tweet
    tweets(limit: Int!, nextToken: String): TweetConnection

    # search functionality is available in elasticsearch integration
    searchTweetsByKeyword(keyword: String!): TweetConnection
}

schema {
    query: Query
    mutation: Mutation
    subscription: Subscription
}

query

Directory Layout

.
├── /app-client/                             # React JS Client Integrations
│   ├── /appsync-client                         # Appsync Client Itegrations
│   │   ├── /public/                            # front End Utils
│   │   │   ├── /index.html                     # main html file to render react app
│   │   │   ├── /...                            # front end metadata
│   │   ├── /src/                               # react app code logic
│   │   │   ├── /components/                    # react components
│   │   │   ├── /App.js                         # react application logic
│   │   │   ├── /index.js                       # react dom render
│   │   │   ├── /aws-exports.js                 # AWS Authentication
│   │   │   ├── /...                            # etc.
│   │   ├── /package.json                       # react app dependencies
│   │   ├── /serverless.yml                     # Serverless yaml for AWS deployment
│   ├── /apollo-client                       # Apollo Client Itegrations
│   │   ├── /public/                            # front End Utils
│   │   │   ├── /index.html                     # main html file to render react app
│   │   │   ├── /...                            # front end metadata
│   │   ├── /src/                               # react app code logic
│   │   │   ├── /components/                    # react components
│   │   │   ├── /App.js                         # react application logic
│   │   │   ├── /index.js                       # react dom render
│   │   │   ├── /...                            # etc.
│   │   ├── /package.json                       # react app dependencies
│   │   ├── /serverless.yml                     # Serverless yaml for AWS deployment
├── /app-backend/                            # Server Backend Integrations
├   ├── /appsync/                               # AWS Appsync Integrations
├   ├   ├── /dynamodb/*                         # AWS Appsync Dynamodb 
├   ├   ├── /elasticsearch/*                    # AWS Appsync Elasticsearch
├   ├   ├── /lambda/                            # AWS Appsync Lambda
│   ├── /dynamodb                            # Integration with DynamodDB Backend
│   │   ├── /seed-data/                         # seed test data
│   │   │   ├── /create_seed_data.js            # Create Seed data to be inserted in dynamodb local and remote
│   │   │   ├── /insert_seed_data_prod.js       # Insert seed data in aws dynamodb (serverless)
│   │   │   ├── /sample-query.txt               # Test Query on DynamoDB Local Client http://localhost:8000
│   │   ├── /handler.js                         # AWS Lambda - Apollo Lambda Server
│   │   ├── /package.js                         # server side dependencies
│   │   ├── /resolvers.js                       # graphql resolvers
│   │   ├── /schema.js                          # graphql schema
│   │   ├── /serverless.yml                     # Serverless yaml for AWS deployment
│   │   ├── /webpack.config.js                  # Webpack server side code with ES6
│   ├── /rest-api                           # Integration with REST API Backend
│   │   ├── /handler.js                         # AWS Lambda - Apollo Lambda Server
│   │   ├── /package.js                         # server side dependencies
│   │   ├── /resolvers.js                       # graphql resolvers
│   │   ├── /schema.js                          # graphql schema
│   │   ├── /serverless.yml                     # Serverless yaml for AWS deployment
│   │   ├── /webpack.config.js                  # Webpack server side code with ES6
│   ├── /rds                                # Integrations for PostGres, MySQL and Aurora Backend
│   │   ├── /seed-data/                         # seed test data
│   │   │   ├── /create_seed_data.js            # Create Seed data to be inserted in dynamodb local and remote
│   │   │   ├── /seed_local.js                  # Insert seed data in aws dynamodb (serverless)
│   │   │   ├── /seed_prod.js                   # Test Query on DynamoDB Local Client http://localhost:8000
│   │   ├── /migrations/                        # Create DDL statements
│   │   ├── /knexfile.js                        # Database Configurations 
│   │   ├── /handler.js                         # AWS Lambda - Apollo Lambda Server
│   │   ├── /package.js                         # server side dependencies
│   │   ├── /resolvers.js                       # graphql resolvers
│   │   ├── /schema.js                          # graphql schema
│   │   ├── /serverless.yml                     # Serverless yaml for AWS deployment
│   │   ├── /webpack.config.js                  # Webpack server side code with ES6
├── /config/                                # Configuration files
│   ├── /security.env.local                     # local config
│   ├── /security.env.prod                      # production config

Coming Soon

  1. Schema Stitching
  2. Lambda Backend: GraphCool, Druid
  3. Aggregations at Scale - Druid
  4. Lambda Backend: Authentication and Authorization
  5. Lambda Backend: Pagination
  6. Swagger Integration
  7. Integration with Azure, IBM and Google Coud

Who uses Serverless GraphQL Apollo?

As the Serverless GraphQL Apollo community grows, we'd like to keep track of who is using the platform. Please send a PR with your company name and @githubhandle if you may.

Currently officially using Serverless GraphQL Apollo :

  1. Serverless @nikgraf
  2. Glassdoor @sid88in
  3. @pradel
  4. EMC School @JstnEdr

Feedback

Send your questions or feedback at: @nikgraf, @sidg_sid