Coder Social home page Coder Social logo

serverless-graphql's Introduction

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
  • 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

serverless-graphql's People

Contributors

amerani avatar andreimc avatar austencollins avatar bboure avatar braco avatar brettstack avatar chownation avatar daviskoh avatar eahefnawy avatar helfer avatar jstnedr avatar kevinold avatar laardee avatar lukepereira avatar marclar avatar mickadoua avatar minibikini avatar mpigsley avatar muke5hy avatar nikgraf avatar ojongerius avatar pmuens avatar pradel avatar ryansb avatar serpentblade avatar sid88in avatar stan-devproject avatar timsuchanek avatar timsvoice avatar tteltrab avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

serverless-graphql's Issues

Multisite support

Hi, what do you think about the possibility to add some sort of multisite support?
For example, it could be used an header to define the site name and use this as reference in a table fields (shared table for each site), or maybe for table name's suffix (each sites could have their table).

use SNS for sending graphql queries

I am not sure if this would work at all, but while working on a graphql project, I noticed that the API Gateway was not really being used much for a graphql project compared to a rest project. There is only one endpoint, and caching is not as useful due to the custom requests. Also, API gateway is relatively expensive compared to other parts of the serverless stack ($3.50 per million requests). I was wondering if I could use SNS instead, with a graphql topic and a lambda controlling incoming messages.I could send requests to my lambda by publishing to the topic, then I could send a http response to the appropriate client as a message. The only reason I am considering this is because SNS is only $.60 per million requests for http, so with a large app this could save a lot of money. Would this work? Would the latency be too high? Thanks!

npm run deploy:frontend failing

Node version 7.2.0
NPM version 3.10.9

npm run deploy:frontend is failing (npm run deploy:api is working).

> NODE_ENV=production env-cmd foundation/environment/security.env.prod webpack --config foundation/webpack/webpack.prod.js -p && cp ./app/favicon.ico ./build/frontend/favicon.ico

   [1] multi main 28 bytes {0} [built]
    + 1 hidden modules

npm ERR! Darwin 16.1.0
npm ERR! argv "/Users/scotttesler/.nvm/versions/node/v7.2.0/bin/node" "/Users/scotttesler/.nvm/versions/node/v7.2.0/bin/npm" "run" "build:frontend"
npm ERR! node v7.2.0
npm ERR! npm  v3.10.9
npm ERR! code ELIFECYCLE
npm ERR! [email protected] build:frontend: `NODE_ENV=production env-cmd foundation/environment/security.env.prod webpack --config foundation/webpack/webpack.prod.js -p && c
p ./app/favicon.ico ./build/frontend/favicon.ico`
npm ERR! Exit status 2
npm ERR!
npm ERR! Failed at the [email protected] build:frontend script 'NODE_ENV=production env-cmd foundation/environment/security.env.prod webpack --config foundation/webpack/web
pack.prod.js -p && cp ./app/favicon.ico ./build/frontend/favicon.ico'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the serverless-graphql package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     NODE_ENV=production env-cmd foundation/environment/security.env.prod webpack --config foundation/webpack/webpack.prod.js -p && cp ./app/favicon.ico ./build/frontend/f
avicon.ico

Error on npm start

I've just cloned this repo on my machine, following the docs int he readme I've installed all dependencies using yarn and started the application with npm, the api/config.js file is generated, but straight after that the app crashes because of the following:

throw new WebpackOptionsValidationError(webpackOptionsValidationErrors);
                ^

WebpackOptionsValidationError: Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
 - configuration has an unknown property 'progress'. These properties are valid:
   object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry, externals?, loader?, module?, name?, node?, output?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, stats?, target?, watch?, watchOptions? }
   For typos: please correct them.
   For loader options: webpack 2 no longer allows custom properties in configuration.
     Loaders should be updated to allow passing options via loader options in module.rules.
     Until loaders are updated one can use the LoaderOptionsPlugin to pass these options to the loader:
     plugins: [
       new webpack.LoaderOptionsPlugin({
         // test: /\.xxx$/, // may apply this only for some modules
         options: {
           progress: ...
         }
       })
     ]
 - configuration.resolve has an unknown property 'packageMains'. These properties are valid:
   object { alias?, aliasFields?, cachePredicate?, descriptionFiles?, enforceExtension?, enforceModuleExtension?, extensions?, fileSystem?, mainFields?, mainFiles?, moduleExtensions?, modules?, plugins?, resolver?, symlinks?, unsafeCache?, useSyncFileSystemCalls? }
 - configuration.resolve.extensions[0] should not be empty.
    at webpack (/....../serverless-graphql-apollo/node_modules/webpack/lib/webpack.js:19:9)
    at Object.<anonymous> (/....../serverless-graphql-apollo/foundation/devServer/index.js:13:18)
    at Module._compile (module.js:570:32)
    at loader (/....../serverless-graphql-apollo/node_modules/babel-register/lib/node.js:144:5)
    at Object.require.extensions.(anonymous function) [as .js] (/....../serverless-graphql-apollo/node_modules/babel-register/lib/node.js:154:7)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
    at Function.Module.runMain (module.js:604:10)
    at /....../serverless-graphql-apollo/node_modules/babel-cli/lib/_babel-node.js:159:24
    at Object.<anonymous> (/....../serverless-graphql-apollo/node_modules/babel-cli/lib/_babel-node.js:160:7)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
[nodemon] app crashed - waiting for file changes before starting...

Any idea of what is wrong?

Use Environment Variables to set API_URL

It seems wrong to have to modify a Flux action to set the API root. This should probably be done through the webpack Define plugin:

// In webpack.conf.js
const isProduction = process.env.NODE_ENV === 'production';
...
plugins: [
    new webpack.DefinePlugin({
        // TODO: Set `API_URL` to your api/stage endpoint eg. https://{{API_ID}}.execute-api.us-east-1.amazonaws.com/{{STAGE_NAME}}
        // run `aws apigateway get-rest-apis` to get a list of your apis and their ids, and use the stage name you specified when setting up the project
        // alternatively, use your custom domain if you have set one up
        "process.env.API_URL": JSON.stringify(isProduction ? process.env.API_URL : "http://localhost:3000"),
    }),
]

In Actions/index:

export const API_URL = process.env.API_URL;
if (!API_URL) {
    console.error('Set `API_URL` environment variable to your stage endpoint')
}

Error cloning / installing

Steps:

  1. git clone [email protected]:serverless/boilerplate-graphql.git
  2. cd boilerplate-graphql
  3. npm install
  4. cd back/api
  5. npm install
  6. cd ../..
  7. sls project init

Results in: Error: Cannot find module 'jsesc'

Bcryptjs uses sync functions

Why do you use synchronous versions of bcryptjs functions ?

user.password_hash = bcryptjs.hashSync(user.password, 10);

could be written

bcryptjs.hash(user.password, 10, function(err, hash) {
    user.password_hash = hash
    ....
});

Explanation of project

Whenever I look at a boilerplate project, the three questions I always have are 'What is this?', 'Where is everything?' and 'What parts do I need to implement?'.

It would be awesome if those questions were explicitly answered in the README. To help answer those questions, it could be helpful to have a simple diagram to show the architecture of the project. draw.io is a good free diagram tool.

Thoughts?

Alternative Architectures

I have been trying out GraphQL with my own projects recently. It seems to me that there are two approaches to a GraphQL API:

  1. Monolithic GraphQL handler
  2. GraphQL Backend for Front End

This project takes the monolithic approach, which is probably best for a boilerplate. It's easier to manage but it does have downsides. Like any monolith, as this grows it will be harder to manage the GraphQL handler and all the data the service owns. It also potentially violates the Principal of Least Access by having one handler access a wide set of data.

For those reasons, I think a Backend for Frontend approach might be better long term. This is a diagram from the presentation I gave recently

screen shot 2016-10-16 at 7 35 38 am

The idea is that the GraphQL API, User Service and Moisture Service can be three separate microservices. The advantages of this is that it adheres to the principal of least access and it increases cohesion and reduces coupling.

I don't think that this design should be used for the boilerplate. It's possibly too complex for people that just want to get started. But, it would be good to make people aware of this design so they understand their options.

What do you think?

Tests Needed

We need some basic tests for GraphQL User CRUD operations.

`sls project` does not work

To get started, the docs say to install the serverless package and then run

sls project install serverless-graphql

I've also tried with sls -m my-project-name project install serverless-graphql

This yields:

Serverless Error ---------------------------------------

 command "project" not found, Run "serverless help" for
 a list of all available commands.

SyntaxError: Unterminated regular expression (1:2)

Node version 7.4.0
NPM version 4.0.5

npm start

> [email protected] start /Users/scott/Documents/Other/serverless-graphql-apollo
> npm run generate:config:local && MOCKED_DATABASE=true env-cmd foundation/environment/security.env.local nodemon ./foundation/devServer --ignore app --exec babel-node


> [email protected] generate:config:local /Users/scott/Documents/Other/serverless-graphql-apollo
> env-cmd foundation/environment/security.env.local npm run generate:config


> [email protected] generate:config /Users/scott/Documents/Other/serverless-graphql-apollo
> node foundation/generateConfig/index.js

api/config.js file was generated
[nodemon] 1.11.0
[nodemon] to restart at any time, enter `rs`
[nodemon] watching: *.*
[nodemon] starting `babel-node ./foundation/devServer`
App is now running on http://localhost:3000
{ SyntaxError: Unterminated regular expression (1:2)
    at Parser.pp$4.raise (/Users/scott/Documents/Other/serverless-graphql-apollo/node_modules/acorn/dist/acorn.js:2454:13)
    at Parser.pp$7.readRegexp (/Users/scott/Documents/Other/serverless-graphql-apollo/node_modules/acorn/dist/acorn.js:3023:51)
    at Parser.pp$7.readToken_slash (/Users/scott/Documents/Other/serverless-graphql-apollo/node_modules/acorn/dist/acorn.js:2843:50)
    at Parser.pp$7.getTokenFromCode (/Users/scott/Documents/Other/serverless-graphql-apollo/node_modules/acorn/dist/acorn.js:2969:17)
    at Parser.pp$7.readToken (/Users/scott/Documents/Other/serverless-graphql-apollo/node_modules/acorn/dist/acorn.js:2714:15)
    at Parser.pp$7.nextToken (/Users/scott/Documents/Other/serverless-graphql-apollo/node_modules/acorn/dist/acorn.js:2705:13)
    at Parser.pp$7.next (/Users/scott/Documents/Other/serverless-graphql-apollo/node_modules/acorn/dist/acorn.js:2650:8)
    at Parser.pp$3.parseParenAndDistinguishExpression (/Users/scott/Documents/Other/serverless-graphql-apollo/node_modules/acorn/dist/acorn.js:2010:10)
    at Parser.pp$3.parseExprAtom (/Users/scott/Documents/Other/serverless-graphql-apollo/node_modules/acorn/dist/acorn.js:1960:17)
    at Parser.parseExprAtom (/Users/scott/Documents/Other/serverless-graphql-apollo/node_modules/acorn-dynamic-import/lib/inject.js:55:31)
    at Parser.pp$3.parseExprSubscripts (/Users/scott/Documents/Other/serverless-graphql-apollo/node_modules/acorn/dist/acorn.js:1854:19)
    at Parser.pp$3.parseMaybeUnary (/Users/scott/Documents/Other/serverless-graphql-apollo/node_modules/acorn/dist/acorn.js:1831:17)
    at Parser.pp$3.parseExprOps (/Users/scott/Documents/Other/serverless-graphql-apollo/node_modules/acorn/dist/acorn.js:1773:19)
    at Parser.pp$3.parseMaybeConditional (/Users/scott/Documents/Other/serverless-graphql-apollo/node_modules/acorn/dist/acorn.js:1756:19)
    at Parser.pp$3.parseMaybeAssign (/Users/scott/Documents/Other/serverless-graphql-apollo/node_modules/acorn/dist/acorn.js:1733:19)
    at Parser.pp$3.parseExpression (/Users/scott/Documents/Other/serverless-graphql-apollo/node_modules/acorn/dist/acorn.js:1709:19) pos: 2, loc: Position { line: 1, column: 2 }, raisedAt: 10 }
webpack built f9904cf31dc89f8bbce2 in 4484ms

Missing Authentication Token - GraphiQL

I'm fairly new to GraphQL in general. I followed this repo and everything works as described but when I try to user the GraphiQL app, I run into authentication issues.

graphiql_and_new_issue_ _serverless_serverless-graphql

Where do I get the Authentication Token and how do I use it to connect to the GraphQL Endpoint?

Passwords not salted

Hi guys,

I just glanced over the code, and it looks like the passwords are not salted - basically each user needs an individual random salt string that is added to the password and used within the hash function.

TypeError: Cannot read property 'users' of undefined when running the client offline

I followed the installation instructions and kept getting the mentioned message in the users index page in the error box at the top. After installing redux-devtools the error is caught by it. In Firefox the message is slightly different: An error occurred: "action.payload.data is undefined". I query the endpoint and db using Graphiql and I get the data without any issues, so I know that the backend it's working.

I get this message in console (Running locally sls offline start) :

Serverless: [200] {"errors":[{"message":"Syntax Error GraphQL request (1:1) Unexpected EOF\n\n1: \n ^\n"}]}

I checked all the code and everything seem in order. I decided to add some debugging lines in the api (back/api/lib/graphql/index.js) to see the data that it was receiving, since in chrome devtools seemed the payload was fine. Then I discovered that it was receiving and "undefined" data payload!

Since I had a similar issue recently in some components I wrote in one of my projects integrating GraphQL, I added the "headers" option (setting Content-type: application/json) into the fetch request and voila! it works now. I am submitting a pull request if you reproduce the problem and find my fix to be useful.

Browser support?

What's the minimum browser versions we plan on supporting? I suggest IE10+ to enable the use of flexbox http://caniuse.com/#feat=flexbox. Flexbox allows for layouts that are otherwise difficult or impossible (at least without significant hacks), but isn't something that can be polyfilled unlike most JS features. IE10 only supports the 2012 syntax, but Autoprefixer (which we should add to Webpack) will take care of that.

Expose GraphQL schema from GET endpoint

My use case is that I'm working with a mobile developer who needs an up-to-date schema.json. I figured I could add a GET /schema endpoint that would assume the existence of a GraphQL endpoint at /data, then run an introspection query against that.

I've already added this to my own project -- should I create a PR?

error: Use of const in strict mode

After cloning / installing the repo (had to install jsesc first, see #24), API endpoints give this error.

I'm guessing it's related to the change to the nodejs4.3 runtime, but I have no idea. The babelify and es2015 preset are still present.

Launch checklist and ETA?

The v0 goals issue was closed, and I see no indication of milestones before this repo is made public. The AWS Serverless team has a hackathon coming up soon and I'd like to demo this. Ideas welcome - always a bonus if you can hook it up to an Echo ;)

Client - Values of to be edited user are not updated

Steps to reproduce:

  • Go to the users table
  • Click on edit in the table
  • Go Back to the users table (wit the browsers back button)
  • Select another user

You'll see the value of the old user.

This has smth. to do with the fact that the state is updated after the component is mounted. We could use Redux form but I don't want to introduce another dependency for such as simple problem.

Error running offline: Syntax Error GraphQL request (1:1) Unexpected EOF

I ran into this issue when trying to work offline (both backend and front end). I was able to fix the issue by adding the content-type header. I see that this project is not using the latest version of serverless-offline and a change there could possibly address the issue. Otherwise the simple fix below would also unblock.

Before (not working):

return (dispatch) => fetch(`${API_URL}/data/`, {
    method: 'POST',
    body: JSON.stringify(query)
  }).then(...

After (working):

  var testHeaders = new Headers();
  testHeaders.append("Content-Type", "application/json");

  return (dispatch) => fetch(`${API_URL}/data/`, {
    method: 'POST',
    body: JSON.stringify(query),
    headers: testHeaders
  })
  .then(...

Error:

Serverless: POST /data (λ: data)  
Serverless: [200] {"errors":[{"message":"Syntax Error GraphQL request (1:1) Unexpected EOF\n\n1: \n   ^\n"}]}

Add Validation

We need validation logic for our data. Not sure whether this should be within GraphQL or outside of it.

Function Names are the Same between Stages

I'm setting up an application that will have two stage: integration and production. Ideally, I would publish to integ, make sure it looks good, then publish to production. I set that up using serverless-graphql, but the functions appear to be deploying to the exact same resource.

If there are two stages in a single region, shouldn't their functions be distinct?

The specified bucket does not exist

Please help me. I try to deploy serverless but this error appear when try to excecute

serverless --stage=production deploy 

into npm run deploy:api step

here is the cli output

Serverless Error ---------------------------------------

     The specified bucket does not exist

  Get Support --------------------------------------------
     Docs:          docs.serverless.com
     Bugs:          github.com/serverless/serverless/issues

  Your Environment Information -----------------------------
     OS:                 darwin
     Node Version:       6.2.0
     Serverless Version: 1.4.0

classnames in html file not correct

it seems the webpack is not including the class names correclty in the html. I can only guess that the HtmlWebpackPlugin is doing something wrong with the html. cant figure it out myself though

HELP WANTED: Relay example

Would be great if there's an example of this using Relay instead of Redux.

It would make more sense to use Relay with GraphQL than Redux IMO.

Authorization and Permission Handling

We're going to move the auth logic into a separate file which will be easier for people to add their own custom auth logic to. We also need to add permission handling here, though we're not sure on the best way to do permission verification w/ GraphQL.

Perhaps each resolve function for collections include required permissions and those are passed into the authorize method, like this: authorize(token, requiredPermissions). The JWToken can contain permissions within it. These will be checked against the permissions hardcoded in each resolve function via an authorize method.

Do you have any thoughts on this?

cc @pmuens @minibikini @eahefnawy @breandr

Rename project to serverless-graphql-boilerplate

We've renamed the project several times (and discussed this extensively) but I think that the "boilerplate" is missing in the name.

Recently I've recommended this project to another developer and he was like "Ah that's a boilerplate! At first I thought that this is a kind of extension or plugin so that GraphQL works with Serverless".
Heard similar comments about it a few times.

So I would propose to go with "serverless-graphql-boilerplate". It's a small change but I think that this makes it more accessible for starters / people who are searching for Serverless boilerplates.

Recomended way to split graphql API in different microservices

Hello,

I would like to split my graphql API in different microservices. With REST this is quite easy because every route has its own microservice/lambda function. When using GraphQL, I have only one route/microservice, which has to handle the routing. Is there a recommended possibility in AWS to replace the normal routing GraphQL lambda function with a cheaper alternative in AWS?

For example:
query users --> getUsers lambda function
mutation login --> signIn lambda function
...

When I want to outsource my code, then I have to pay the two times: the GraphQL and the service lambda function. All in one, I have the struggle of separating my code and having one single and flexible API.

Thanks in advance.

How To Add Further Application/Business Logic

Using GraphQL in a Lambda function is promising. We've reduced a REST API with many endpoints into a single endpoint Graph API connected to one Lambda. This results in less administration, less code, and a great developer experience on the client-side.

However, this encourages adding lots of logic into that single Lambda function, resulting in a monolithic architecture. How can we make room for people to easily add application/business logic, in a microservices way, without encouraging a monolithic Lambda function?

Perhaps, in the GraphQL resolve functions, we could invoke other Lambda functions that contain further application/business logic. These separate Lambdas could be invoked synchronously, but would most likely be invoked asynchronously to reduce latency. For example, a user could be added to a transactional email list in a separate lambda function, after they have been created in the graphql function.

What do you think of the above approach and does anyone have other suggestions?

cc @pmuens @doapp-ryanp @minibikini @eahefnawy @flomotlik @mwawrusch @erikerikson @kevinold

Clarify AWS credentials requirements for local DB

It seems that the setupdb plugin needs the [default] profile in ~/.aws/credentials to have the same aws_access_key_id and aws_secret_access_key as the profile in admin.dev.

I tried setting AWS_DEFAULT_PROFILE to the profile in admin.dev, but didn't work.

Is this a bug?

Here the error I get:

mutation createUserTest { createUser ....

"errors": [
    {
      "message": "Missing credentials in config",
      "originalError": {
        "cause": {
          "message": "Missing credentials in config",
          "code": "CredentialsError",
          "time": "2016-05-04T14:37:16.127Z",
          "originalError": {
            "message": "Could not load credentials from any providers",
            "code": "CredentialsError",
            "time": "2016-05-04T14:37:16.127Z",
            "originalError": {
              "message": "Connection timed out after 1000ms",
              "code": "TimeoutError",
              "time": "2016-05-04T14:37:16.127Z"
            }
          }
        },
        "isOperational": true,
        "code": "CredentialsError",
        "time": "2016-05-04T14:37:16.127Z",
        "originalError": {
          "message": "Could not load credentials from any providers",
          "code": "CredentialsError",
          "time": "2016-05-04T14:37:16.127Z",
          "originalError": {
            "message": "Connection timed out after 1000ms",
            "code": "TimeoutError",
            "time": "2016-05-04T14:37:16.127Z"
          }
        }
      }
    }
  ]

Rename `back` to `backend`?

I was reading through the readme to run through the setup. The name back initially was confusing. What do you think about renaming it to backend?

Server-Side Caching

We'd like to offer easy server-side caching, but we can't do that right now with a single endpoint containing only a POST request to API Gateway.

We should create a second Endpoint on the existing data Lambda which features a GET method. The GraphQL request should be provided in a query string, which API Gateway needs for caching.

Not sure what type of challenges we'll run into implementing this, but if this works, great!

@kevinold @pmuens @breandr Do you see any potential issues with this?

V0 Goals

The goal here is not just to create the ultimate boilerplate project for building serverless applications, but to create an application boilerplate with the lowest total cost of ownership (e.g., code, administration, cost) by leveraging new tech (e.g., Lambda, GraphQL). Here is what the initial implementation should include:

  • Create scaffolding: api, events, utils folders for lambdas
  • The API should be a Graph API served via one Lambda and endpoint
  • Implement a basic Users CRUD
  • Authentication and Authorization should be done via the viewer pattern in GraphQL
  • Add validation logic for writes
  • Serverless Babel Runtime should be included to support ES6 syntax
  • Serverless Client S3 Plugin should be used to deploy client-side assets
  • A basic web application front-end should be included. Very minimal.
  • Include Serverless V0.5 as a dependency

rename the project to serverless-boilerplate-monolithic

I feel like it's very important to communicate that this is not the one and only way to use serverless. People are very quick in their assumptions and judgements, and going back to RPC style programming won't sit well with a lot of folks.

Just my 2 cents...

Invalid mapping expression specified: *

Hi Nik, we talked on Gitter.

what did not work for me:

if I run the code exactly as you provided I get following error:

    Serverless Error ---------------------------------------

            An error occurred while provisioning your stack: ApiGatewayMethodGraphqlPost
            - Invalid mapping expression specified: Validation Result:
            warnings : [], errors : [Invalid mapping expression
            specified: *].

    Get Support --------------------------------------------
            Docs:          docs.serverless.com
            Bugs:          github.com/serverless/serverless/issues

    Your Environment Infomation -----------------------------
            OS:                 darwin
            Node Version:       7.0.0
            Serverless Version: 1.0.3

what I tried:

based on https://serverless.com/framework/docs/providers/aws/events/apigateway/
at # Enabling CORS with the Lambda Integration Method
it is not needed to define Access-Control-Allow-Methods, as this is set automatically.

I did delete following from the serverless.yaml:

    response:
      headers:
        Access-Control-Allow-Origin: "*"

then it deploys as described in your readme.

However, now my browser throws a:

    No 'Access-Control-Allow-Origin' header is present on the requested resource.
    Origin 'xxxx.s3-website-us-east-1.amazonaws.com' is therefore not allowed access. 
    The response had HTTP status code 502.

Now I was wondering if I should include "'Access-Control-Allow-Origin': '*'" in the returned headers. However apparently this is only needed with a proxy setup.

Well I am bit lost here.

Maybe it is something different I have overlooked that kept my from deploying in the first place?

Thanks a lot for your help.

Cheers
Andreas

one more thing:
it might be good to say briefly in the readme that the AWS Command line tool is needed to be installed.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.