All Projects → serverless-components → Aws App Sync

serverless-components / Aws App Sync

Licence: other
Easily Deploy AWS AppSync GraphQL APIs Using Serverless Framework Components

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to Aws App Sync

Webiny Js
Enterprise open-source serverless CMS. Includes a headless CMS, page builder, form builder and file manager. Easy to customize and expand. Deploys to AWS.
Stars: ✭ 4,869 (+1765.52%)
Mutual labels:  graphql, aws, serverless, serverless-framework
Graphql Serverless
Sample project to guide the use of GraphQL and Serverless Architecture.
Stars: ✭ 28 (-89.27%)
Mutual labels:  graphql, aws, serverless, serverless-framework
Json Serverless
Transform a JSON file into a serverless REST API in AWS cloud
Stars: ✭ 108 (-58.62%)
Mutual labels:  graphql, aws, serverless, serverless-framework
Serverlessbydesign
A visual approach to serverless development. Think. Build. Repeat.
Stars: ✭ 254 (-2.68%)
Mutual labels:  aws, serverless, serverless-framework
Serverless Prisma
AWS Serverless Prisma Boilerplate
Stars: ✭ 126 (-51.72%)
Mutual labels:  graphql, aws, serverless
Graphql Recipes
A list of GraphQL recipes that, when used with the Amplify CLI, will deploy an entire AWS AppSync GraphQL backend.
Stars: ✭ 137 (-47.51%)
Mutual labels:  graphql, aws, serverless
Aws Auto Remediate
Open source application to instantly remediate common security issues through the use of AWS Config
Stars: ✭ 191 (-26.82%)
Mutual labels:  aws, serverless, serverless-framework
Panther
Detect threats with log data and improve cloud security posture
Stars: ✭ 885 (+239.08%)
Mutual labels:  graphql, aws, serverless
Conference App In A Box
Full stack & cross platform app customizable & themeable for any event or conference.
Stars: ✭ 693 (+165.52%)
Mutual labels:  graphql, aws, serverless
Aws Serverless Appsync Loyalty
Unicorn Loyalty: E-Commerce Serverless GraphQL Loyalty Sample App
Stars: ✭ 110 (-57.85%)
Mutual labels:  graphql, aws, serverless
Up
Up focuses on deploying "vanilla" HTTP servers so there's nothing new to learn, just develop with your favorite existing frameworks such as Express, Koa, Django, Golang net/http or others.
Stars: ✭ 8,439 (+3133.33%)
Mutual labels:  graphql, aws, serverless
Aws Lambda Typescript
This sample uses the Serverless Application Framework to implement an AWS Lambda function in TypeScript, deploy it via CloudFormation, publish it through API Gateway to a custom domain registered on Route53, and document it with Swagger.
Stars: ✭ 228 (-12.64%)
Mutual labels:  aws, serverless, serverless-framework
Serverless Chrome
🌐 Run headless Chrome/Chromium on AWS Lambda
Stars: ✭ 2,625 (+905.75%)
Mutual labels:  aws, serverless, serverless-framework
Retinal
🏙 Retinal is a Serverless AWS Lambda service for resizing images on-demand or event-triggered
Stars: ✭ 208 (-20.31%)
Mutual labels:  aws, serverless, serverless-framework
Bootcamp 2021
Fusing Serverless Cloud Computing, Infrastructure as Code, Graph Databases, AI, and IoT Technologies and preparing for Operation Unicorn Startups
Stars: ✭ 55 (-78.93%)
Mutual labels:  graphql, aws, serverless
Write With Me
Real-time Collaborative Markdown Editor
Stars: ✭ 81 (-68.97%)
Mutual labels:  graphql, aws, serverless
Serverless Aws Alias
Alias support for Serverless 1.x
Stars: ✭ 171 (-34.48%)
Mutual labels:  aws, serverless, serverless-framework
Components
The Serverless Framework's new infrastructure provisioning technology — Build, compose, & deploy serverless apps in seconds...
Stars: ✭ 2,259 (+765.52%)
Mutual labels:  aws, serverless, serverless-framework
Serverless
This is intended to be a repo containing all of the official AWS Serverless architecture patterns built with CDK for developers to use. All patterns come in Typescript and Python with the exported CloudFormation also included.
Stars: ✭ 1,048 (+301.53%)
Mutual labels:  graphql, aws, serverless
This Or That
This or that - Real-time atomic voting app built with AWS Amplify
Stars: ✭ 87 (-66.67%)
Mutual labels:  graphql, aws, serverless

Serverless AppSync Component

Serverless AppSync Component

The AppSync Serverless Component allows you to easily and quickly deploy GraphQL APIs on AWS, and integrate them with AWS Lambda, DynamoDB & others. It supports all AWS AppSync features, while offering sane defaults that makes working with AppSync a lot easier without compromising on flexibility.

Features

  • [x] Fast Deployments (~10 seconds on average)
  • [x] Create New APIs or Reuse Existing Ones
  • [x] Supports Custom Domains with CDN & SSL Out of the Box
  • [x] Supports Custom AppSync Service Role
  • [x] Supports Lambda Data Source
  • [x] Supports DynamoDB Data Source
  • [x] Supports ElasticSearch Data Source
  • [x] Supports Relational Database Data Source
  • [x] Supports API Keys Authentication
  • [x] Supports Cognito User Pools Authentication
  • [x] Supports OpenID Connect Authentication
  • [x] Supports AppSync Functions

Contents

  1. Install
  2. Create
  3. Configure
  4. Deploy

1. Install

$ npm install -g serverless

2. Create

Just create the following simple boilerplate:

$ touch serverless.yml # more info in the "Configure" section below
$ touch schema.graphql # your graphql schema file
$ touch index.js       # only required if you use a Lambda data source
$ touch .env           # your AWS api keys
# .env
AWS_ACCESS_KEY_ID=XXX
AWS_SECRET_ACCESS_KEY=XXX

3. Configure

Basic Configuration

The following is a simple configuration that lets you get up and running quickly with a Lambda data source. Just add it to the serverless.yml file:

myLambda:
  component: "@serverless/aws-lambda"
  inputs:
    handler: index.handler
    code: ./

myAppSyncApi:
  component: "@serverless/aws-app-sync"
  inputs:
    # creating the API and an API key
    name: Posts
    authenticationType: API_KEY
    apiKeys:
      - myApiKey

    # defining your lambda data source
    dataSources:
      - type: AWS_LAMBDA
        name: getPost
        config:
          lambdaFunctionArn: ${myLambda.arn}

    # mapping schema fields to the data source
    mappingTemplates:
      - dataSource: getPost
        type: Query
        field: getPost

This configuration works with the following example schema. Just add it to the schema.graphql file right next to serverless.yml:

schema {
  query: Query
}

type Query {
  getPost(id: ID!): Post
}

type Post {
  id: ID!
  author: String!
  title: String
  content: String
  url: String
}

You'll also need to add the following handler code for this example to work:

exports.handler = async event => {
  var posts = {
    "1": {
      id: "1",
      title: "First Blog Post",
      author: "Eetu Tuomala",
      url: "https://serverless.com/",
      content:
        "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s."
    },
    "2": {
      id: "2",
      title: "Second Blog Post",
      author: "Siddharth Gupta",
      url: "https://serverless.com",
      content:
        "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s."
    }
  };

  return posts[event.id];
};

For more advanced usage, keep reading!

Custom Domains

You could optionally specify a custom domain for your GraphQL API, just add a domain property to the app sync component inputs:

myAppSyncApi:
  component: "@serverless/aws-app-sync"
  inputs:
    domain: api.example.com # add your custom domain here
    name: Posts
    # ... rest of config here

This would create a CloudFront distribution (aka CDN) for your AppSync API, which reduces request latency significantly, and would give you an SSL certificate out of the box powered by AWS ACM.

Please note that your domain (example.com in this example) must have been purchased via AWS Route53 and available in your AWS account. For advanced users, you may also purchase it elsewhere, then configure the name servers to point to an AWS Route53 hosted zone. How you do that depends on your registrar.

Create or Reuse APIs

The AppSync component allows you to either create an AppSync API from scratch, or integrate with an existing one. Here's how to create a new API:

# serverless.yml

myAppSync:
  component: '@serverless/aws-app-sync'
  inputs:
    name: 'my-api-name' # specifying a name creates a new API
    domain: api.example.com # example.com must be available in your AWS Route53
    authenticationType: 'API_KEY'
    apiKeys:
      - 'myApiKey'
    mappingTemplates:
      - dataSource: 'dynamodb_ds'
        type: 'Query'
        field: 'getMyField'
        request: 'mapping-template-request.vtl'
        response: 'mapping-template-response.vtl'
    functions:
      - dataSource: 'dynamodb_ds'
        name: 'my-function'
        request: 'function-request.vtl'
        response: 'function-response.vtl'
    dataSources:
      - type: 'AMAZON_DYNAMODB'
        name: 'dynamodb_ds'
        config:
          tableName: 'my-dynamo-table'
    schema: 'schema.graphql' # optional. Default behavior would look for schema.graphql file in the cwd

Reuse an existing AWS AppSync service by adding replacing the name input with apiId. This way the component will modify the AppSync service by those parts which are defined.

# serverless.yml

myAppSync:
  component: '@serverless/aws-app-sync'
  inputs:
    apiId: 'm3vv766ahnd6zgjofnri5djnmq'
    mappingTemplates:
      - dataSource: 'dynamodb_2_ds'
        type: 'Query'
        field: 'getMyField'
        request: 'mapping-template-request.vtl'
        response: 'mapping-template-response.vtl'
    dataSources:
      - type: 'AMAZON_DYNAMODB'
        name: 'dynamodb_2_ds'
        config:
          tableName: 'my-dynamo-table'

Authentication

The app using AppSync API can use four different methods for authentication.

  • API_KEY - Api keys
  • AWS_IAM - IAM Permissions
  • OPENID_CONNECT - OpenID Connect provider
  • AMAZON_COGNITO_USER_POOLS - Amazon Cognito user pool

When using OpenID connect method, inputs has to contain openIDConnectConfig block.

myAppSync:
  component: '@serverless/aws-app-sync'
  inputs:
    authenticationType: 'OPENID_CONNECT'
    openIDConnectConfig:
      issuer: 'NNN'
      authTTL: '1234'
      clientId: 'NNN'
      iatTTL: '1234'

When using Amazon Cognito user pools, userPoolConfig has to be defined.

myAppSync:
  component: '@serverless/aws-app-sync'
  inputs:
    authenticationType: 'AMAZON_COGNITO_USER_POOLS'
    userPoolConfig:
      awsRegion: 'us-east-1'
      defaultAction: 'ALLOW'
      userPoolId: 'us-east-1_nnn'

ApiKey can be created and modified by defining apiKeys.

myAppSync:
  component: '@serverless/aws-app-sync'
  inputs:
    apiKeys:
      - 'myApiKey1' # using default expiration data
      - name: 'myApiKey2'
        expires: 1609372800
      - name: 'myApiKey3'
        expires: '2020-12-31'

Schema

You can define the schema of your GraphQL API by adding it to the schema.graphql file right next to serverless.yml. Here's a simple example schema:

schema {
  query: Query
}

type Query {
  getPost(id: ID!): Post
}

type Post {
  id: ID!
  author: String!
  title: String
  content: String
  url: String
}

Alternatively, if you have your schema file at a different location, you can specify the new location in serverless.yml

  inputs:
    name: myGraphqlApi
    schema: ./path/to/schema.graphql # specify your schema location

Data Sources & Templates

The AppSync component supports 4 AppSync data sources and their corresponding mapping templates. You could add as many data sources as your application needs. For each field (or operation) in your Schema (ie. getPost), you'll need to add a mapping template that maps to a data source.

Here are the data sources that are supported:

Lambda Data Source

Here's an example setup for a Lambda data source:

serverless.yml

myLambda:
  component: "@serverless/aws-lambda"
  inputs:
    handler: index.handler
    code: ./

myAppSyncApi:
  component: "@serverless/aws-app-sync"
  inputs:
    # creating the API and an API key
    name: Posts
    authenticationType: API_KEY
    apiKeys:
      - myApiKey

    # defining your lambda data source
    dataSources:
      - type: AWS_LAMBDA
        name: getPost
        config:
          lambdaFunctionArn: ${myLambda.arn} # pass the lambda arn from the aws-lambda component above
      - type: AWS_LAMBDA
        name: addPost
        config:
          lambdaFunctionArn: ${myLambda.arn} # you could pass another lambda ARN, or the same one if it handles that field

    # mapping schema fields to the data source
    mappingTemplates:
      - dataSource: getPost
        type: Query
        field: getPost
      - dataSource: addPost
        type: Mutation
        field: addPost

        # Minimal request/response templates are added by default that works for 99% of use cases.
        # But you could also overwrite them with your own templates by specifying the path to the template files
        request: request.vtl
        response: response.vtl

index.js

exports.handler = async (event) => {
  var posts = {
    '1': {
      id: '1',
      title: 'First Blog Post',
      author: 'Eetu Tuomala',
      url: 'https://serverless.com/',
      content:
        "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s."
    },
    '2': {
      id: '2',
      title: 'Second Blog Post',
      author: 'Siddharth Gupta',
      url: 'https://serverless.com',
      content:
        "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s."
    }
  }

  return posts[event.id]
}


schema.graphql

schema {
  query: Query
}

type Query {
  getPost(id: ID!): Post
}

type Post {
  id: ID!
  author: String!
  title: String
  content: String
  url: String
}

DynamoDB Data Source

For the DynamoDB data source, you'll need to provide your own request/response templates that works according to your schema. Here's an example setup:

serverless.yml

# create a table with the aws-dynamodb component
myTable:
  component: '@serverless/aws-dynamodb'

appsync:
  component: '@serverless/aws-app-sync'
  inputs:
    name: Posts
    authenticationType: API_KEY
    apiKeys:
      - myApiKey
    dataSources:
      - type: AMAZON_DYNAMODB
        name: Posts
        config:
          tableName: ${myTable.name}
    mappingTemplates:
      - dataSource: Posts
        type: Mutation
        field: addPost
        request: request.vtl
        response: response.vtl

request.vtl

{
    "version" : "2017-02-28",
    "operation" : "PutItem",
    "key" : {
        "id" : { "S" : "${context.arguments.id}" }
    },
    "attributeValues" : {
        "author": { "S" : "${context.arguments.author}" },
        "title": { "S" : "${context.arguments.title}" },
        "content": { "S" : "${context.arguments.content}" },
        "url": { "S" : "${context.arguments.url}" },
        "ups" : { "N" : 1 },
        "downs" : { "N" : 0 },
        "version" : { "N" : 1 }
    }
}

response.vtl

$util.toJson($context.result)

schema.graphql

schema {
  query: Query
  mutation: Mutation
}

type Query {
  getPost(id: ID): Post
}

type Mutation {
  addPost(id: ID!, author: String!, title: String!, content: String!, url: String!): Post!
}

type Post {
  id: ID!
  author: String
  title: String
  content: String
  url: String
  ups: Int!
  downs: Int!
  version: Int!
}

ElasticSearch Data Source

This example uses Amazon ElasticSearch Service running in AWS. The cluster contains ElasticSearch/Kibana sample flight data https://www.elastic.co/guide/en/kibana/current/tutorial-sample-data.html.

serverless.yml

myAppSyncApi:
  component: "@serverless/aws-app-sync"
  inputs:
    # creating the API and an API key
    name: Flights
    authenticationType: API_KEY
    apiKeys:
      - myApiKey

    dataSources:
      - type: AMAZON_ELASTICSEARCH
        name: Flights
        config:
          endpoint: https://search-my-sample-data-abbaabba.us-east-1.es.amazonaws.com

    mappingTemplates:
      - dataSource: Flights
        type: Query
        field: getFlights
        request: request.vtl
        response: response.vtl

request.vtl

The resolver returns 50 latest flights.

{
    "version":"2017-02-28",
    "operation":"GET",
    "path":"/kibana_sample_data_flights/_doc/_search",
    "params":{
        "body": {
            "from": 0,
            "size": 50,
            "query": {
                "match_all": {}
            }
        }
    }
}

response.vtl

[
    #foreach($entry in $context.result.hits.hits)
        ## $velocityCount starts at 1 and increments with the #foreach loop **
        #if( $velocityCount > 1 ) , #end
        $util.toJson($entry.get("_source"))
    #end
]

schema.graphql

type Flight {
	FlightNum: String
	DestAirportID: String
	OriginAirportID: String
}

type Query {
	getFlights: [Flight]
}

schema {
	query: Query
}

After deployment, update ElasticSearch access policy to allow created role by adding following block to statement array.

{
  "Effect": "Allow",
  "Principal": {
    "AWS": "arn:aws:iam::123456789012:role/created-role" <- replace with correct role
  },
  "Action": [
    "es:ESHttpDelete",
    "es:ESHttpHead",
    "es:ESHttpGet",
    "es:ESHttpPost",
    "es:ESHttpPut"
  ],
  "Resource": "arn:aws:es:us-east-1:123456789012:domain/my-sample-data/*" <- replace with correct ElasticSearch domain
}

Relational Database Data Source

This example is using an Amazon Aurora Serverless cluster with PostgreSQL database which is already running in AWS.

The database has two tables, authors table, which contains an id and a fullname columns, and posts table which contains following columns id, title, content, url, and a foreign key fk_authors_id.

serverless.yml

myAppSyncApi:
  component: "@serverless/aws-app-sync"
  inputs:
    # creating the API and an API key
    name: Posts
    authenticationType: API_KEY
    apiKeys:
      - myApiKey

    # Relational database datasource has to be an Amazon Aurora Serverless Cluster with Data API enabled
    # https://docs.aws.amazon.com/appsync/latest/devguide/tutorial-rds-resolvers.html
    dataSources:
      - type: RELATIONAL_DATABASE
        name: Posts
        config:
          awsSecretStoreArn: 'arn:aws:secretsmanager:us-east-1:123456789123㊙️rds-db-credentials/cluster-ABCDEFGHI/admin-aBc1e2'
          databaseName: 'mydatabase'
          dbClusterIdentifier: 'arn:aws:rds:us-east-1:123456789123:cluster:my-serverless-aurora-postgres-1'
          schema: 'public'

    mappingTemplates:
      - dataSource: Posts
        type: Query
        field: getPost
        request: request.vtl
        response: response.vtl

request.vtl

{
    "version": "2018-05-29",
    "statements": [
        "select posts.id, posts.title, posts.content, posts.url, authors.fullname as author from posts, authors where authors.id = posts.fk_authors_id and posts.id = '$ctx.args.id'"
    ]
}

response.vtl

#if($ctx.error)
    $utils.error($ctx.error.message, $ctx.error.type)
#end

$utils.toJson($utils.rds.toJsonObject($ctx.result)[0][0])

schema.graphql

schema {
  query: Query
  mutation: Mutation
}

type Query {
  getPost(id: ID): Post
}

type Mutation {
  addPost(fk_authors_id: Int!, title: String!, content: String!, url: String!): Post!
}

type Post {
  id: ID!
  author: String
  fk_authors_id: Int
  title: String
  content: String
  url: String
}

Functions

4. Deploy

To deploy, just run the following command in the directory containing your serverless.yml file:

$ serverless

After few seconds (up to a minute if it's your first deployment), you should see an output like this:

  myAppSyncApi:
    apiId:   samrhyo7srbtvkpqnj4j6uq6gq
    arn:     arn:aws:appsync:us-east-1:552751238299:apis/samrhyo7srbtvkpqnj4j6uq6gq
    url:     "https://samrhyo7srbtvkpqnj4j6uq6gq.appsync-api.us-east-1.amazonaws.com/graphql"
    apiKeys:
      - da2-coeytoubhffnfastengavajsku
    domain:  "https://api.example.com/graphql"

  9s › myAppSyncApi › done

myApp (master)$

 

New to Components?

Checkout the Serverless Components repo for more information.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].