Serverless GraphQL Examples for AWS AppSync and Apollo
Switch branches/tags
feature/add_appsync_integrations feature/add_appsync_plugin feature/add_aws_neptune feature/add_dynamo_db feature/add_lambda_mutations feature/add_more_mutations feature/add_mutations_elasticsearch feature/add_mutations_in_appsync_client feature/add_polling feature/appsync_docs feature/appsyncplugin feature/automate_appsync_iam feature/aws_amplify feature/aws_xray_integration feature/awsappsync_client feature/batch_insert feature/blog2v feature/blog2 feature/blog3 feature/bring_back_apollo_client feature/create_cognito_user_pool_token feature/diagram_v2 feature/diagram feature/dyanamoxray feature/enhance_appsync_schema feature/enhance_client feature/enhance_es_template feature/enhance_schema feature/final_lambda feature/fix_dynamo feature/fix_readme feature/fixapolloclient feature/graphqlconfig feature/lambda_appsync_plugin feature/lambda_sync feature/persisted_queries feature/rds_sync feature/schema_redesign feature/secure_api feature/simplify_aws_amplify feature/toptweet feature/twitter_rest_api_wrapper feature/update_appsync_plugin feature/update_diagram feature/update_es_schema feature/update_stack_info feature/upgrade_awssdk feature/upgrade_graphql_packages feature/upgrade_playground feature/xray feautre/fix_dims fix/architecture fix_readme fix/schema fixreadme hotfix/apollo_integrations hotfix/appsync_lambda_mutation hotfix/bug hotfix/bugfix hotfix/es_mapping hotfix/fetchpolicy hotfix/fix_build hotfix/fix_build2 hotfix/fix_mapping_template hotfix/fix_rds_data_insertion hotfix/fix_service_name hotfix/fix_subsc hotfix/follow_schema hotfix/lambda_hotfix hotfix/lambda_hotfixes hotfix/minor_fixes_rds hotfix/minor_fixes hotfix/playground hotfix/rds_prod_fixes hotfix/rds_timeout hotfix/readme+build hotfix/readme_v3 hotfix/readme hotfix/readmev4 hotfix/readmev5 hotfix/remove_breaking_change hotfix/remove_failed_tests hotfix/removefiles hotfix/stack hotfix/travisbuild hotfix/update_lambda hotfix/update_readme hotfix/update_readmev2 hotfix/update_readmev3 improve-onboarding improve-readme-2nd-try improve-role master notes remove-graphiql schema update-es-schema update-schema
Nothing to show
Clone or download
Latest commit c8a2ea3 Nov 18, 2018

README.md

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 an 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
  • AWS Appsync (Serverless Offline does not support Appsync at this point)

    • AWS DynamoDB
    • AWS ElasticSearch
    • AWS Lambda
  • Lambda Backend (Serverless Offline Supported)

    • Twitter Rest API
      cd app-backend/rest-api
      yarn start
      

    Generate your Consumer Key and Secret Key for a Twitter App and update config

    • DynamoDB

      cd app-backend/dynamodb
      yarn start
      
    • RDS

      cd app-backend/rds
      yarn start
      
  1. Start FrontEnd (Apollo Client or Appsync Client)
  • For Appsync Backend please select Appsync Client Integration:

    cd app-client/appsync-client/
    yarn start
    
  • For Lambda Backend please select Apollo Client Integration:

    cd app-client/apollo-client/
    yarn start
    

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
  1. 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
  1. 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
  • Lambda Backend (Serverless Offline Supported)

    • Twitter Rest API

      cd app-backend/rest-api
      yarn deploy-prod
      
    • DynamoDB

      cd app-backend/dynamodb
      yarn deploy-prod
      
    • RDS

      • Create RDS Instance. For example - PostGres Tutorial

      • Please make sure connectivity to production RDS instance works (For example: test via razersql)

      • Edit the config/security.env.prod file and replace the DATABASE_URL variable with your amazon rds endpoint (eg: postgres://${username}:{password}@${endpoint):5432/${dbName}).

      • Run the deployment command

        cd app-backend/rds
        yarn deploy-prod
        
  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)
  • Note:

    • For lambda please use apollo-client
    • For appsync backend please use appsync-client
    • Please note that backend is deployed before deploying frontend.
    • You can deploy the client on AWS S3 or Netlify.
  • AWS S3

    • First you will need to choose custom s3 bucket name for client. For ex: s3-firstname-serverless-graphql. Please note that bucket name must be unique across all aws buckets.

    • Now, in app-client/<client-name>/serverless.yml edit the custom.client.bucketName property and replace it the bucket name above.

    • Now, in app-client/<client-name>/package.json edit the homepage property with https://${yourBucketName}.s3-website-us-east-1.amazonaws.com. For ex: https://s3-bucketname-serverless-graphql.s3-website-us-east-1.amazonaws.com

    • Run the deployment command

      cd app-client/<client-name>/
      yarn deploy-s3
      # Your deployment url will be printed on the console
      
    • Your deployment url will be : https://s3.amazonaws.com/[bucket-name]/index.html

  • Netlify

    • First you will need to create a new account. Please see https://www.netlify.com/docs/cli/ for details.

    • Remove homepage property in app-client/<client-name>/package.json. This property is not required while deploying to netlify but is required for aws s3 deployment.

    • The first time you use the cli tool, you’ll be asked to authenticate through the browser. After you authenticate netlify will store an access token in a global ~/.netlify/config

    • Run deployment command

      cd app-client/<client-name>/
      yarn deploy-netlify
      
      • ? No site id specified, create a new site (Y/n) Y
      • ? Path to deploy? (current dir) build
    • Your deployment url will be printed on the console

Example: Appsync Backend Integration

  • GraphQL Schema:
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
}
  • GraphQL Query:

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