DEV Community

Alexander
Alexander

Posted on • Originally published at r11baka.hashnode.dev

How connect appsync and lambda

Intro

The article is not intended for beginners and will not explain what GraphQL is or how to install Node.js or setup aws cli. Instead, it will focus on personal experience and info that hard to find. it's advisable to have some free time, and a healthy sense of curiosity.

What is appsync ?

This is a GraphQL server from AWS Amazon.

In AppSync, resolvers can be written in either JavaScript or can call an external lambda function and this lamda can handle all the logic.I prefer using Lambda because the runtime functionality for resolvers within AppSync is extremely limited. Example of limitations of js resolvers you can see by url https://docs.aws.amazon.com/appsync/latest/devguide/supported-features.html

Here some examples:

  1. applybind, and call methods not are supported.
  2. Function constructors are not supported.
  3. Passing a function as an argument is not supported.
  4. Recursive function calls are not supported.
  5. Async processes are not supported, and promises are not supported.

IMHO Looks terrible. Immposible to write comlex code.

AppSync drawbacks

TLDR: You'll be solving problems that would never have arisen if you had chosen a different approach. For example

With lambda as resolver you have request flow like

  1. A request comes from the user.
  2. AppSync parses the request.
  3. It transforms it into an object and sends it to the Lambda function over the network.
  4. The Lambda function parses it, interacts with the database, computes the response, and sends it back to AppSync.
  5. AppSync delivers the response to the user.

On the other hand with apollo:

  1. A user request arrives.
  2. Apollo parses it.
  3. It handle with same memory process , unlike AppSync, which does it over the network.
  4. The resolver interacts with the database, performs calculations, etc.
  5. And then returns this to the user.

Compared to a GraphQL server,

  1. AppSync introduces an extra network request.
  2. Additionally, in the Lambda scenario, you would have to address the N+1 query problem at the Lambda level, without utilizing the Data Loader pattern.

Some other drawbacks

  1. Also, AppSync does not support documentation in the GraphQL schema using triple quotes ("""), only hardcore "#" comments.
  2. It has not supported documentation within enums for four years now! Link to the issue.

How to connect lambda и appsync ?

I prefer using the Serverless Framework and its associated plugin serverless-appsync-plugin.

Attention, the instructions for the serverless-appsync-plugin on the website https://www.serverless.com/plugins/serverless-appsync-plugin are outdated. Don't use it. Looks at real doc on https://github.com/sid88in/serverless-appsync-plugin/blob/master/README.md.

Quckstart

clone my template repo

git clone https://github.com/R11baka/appsynctemplate && cd appsynctemplate
Enter fullscreen mode Exit fullscreen mode

After that run

npm install
Enter fullscreen mode Exit fullscreen mode

Useful commands that appear after installing the serverless-appsync-plugin.

npx sls appsync validate-schema
Enter fullscreen mode Exit fullscreen mode

Schema validation. It partially ensures that your schema is valid. It won't save you if you have comments within an enum.

What's going on ?

The heart of application and most tricky, from my point of view is serverless.yaml file. Let's try to see

service: appsync-demo  
frameworkVersion: "3"
configValidationMode: "warn"

provider:
  name: aws
  runtime: nodejs18.x
  stage: ${opt:stage, self:custom.defaultStage}
  region: us-west-1
  versionFunctions: true
  logRetentionInDays: 90
  environment:
    AWS_NODEJS_CONNECTION_REUSE_ENABLED: 1

plugins:
  - serverless-appsync-plugin # attach appsync-plugin to serverless
custom:
  defaultStage: dev

appSync:
  name: appsync-demo-${self:provider.stage}
  schema: 'schema.graphql' # path relative to serverless.yaml file
  authentication:
    type: 'API_KEY' # type of auth. Also can be cognito, and custom AWS_LAMBDA
  apiKeys:
    - name: apiKey
      description: dev API key
      expiresAfter: 1M
  dataSources:
    appsyncLambdaDataSource:
      type: AWS_LAMBDA
      name: appsyncLambda
      config:
        functionName: appsyncLambda # name of lambda
  resolvers:
    query:
      type: Query # Hello resolver
      field: hello
      dataSource: appsyncLambdaDataSource 
      kind: UNIT

functions:
  appsyncLambda:
    name: appsyncLambda-${self:provider.stage}
    description: Lambda resolver which accept events from appsync
    timeout: 15
    handler: src/index.handler # points to main entry point
Enter fullscreen mode Exit fullscreen mode

So tricky part is definition datasource, resolver, lambdaname.

  1. Resolver on 36 line points to datasource with name appsyncLambdaDataSource.
  2. appsyncLambdaDataSource point on lambda with name appsyncLambda, which defined on 43 line

How to deploy ?

Deploy to dev

npm sls deploy --stage=dev --verbose
Enter fullscreen mode Exit fullscreen mode

Deploy to live

npx sls deploy --stage=live --verbose
Enter fullscreen mode Exit fullscreen mode

After deploy you will see in console output something like

Stack Outputs:
  AppsyncLambdaLambdaFunctionQualifiedArn: arn:aws:lambda:us-west-1:7412810041:function:appsyncLambda-dev:5
  ServerlessDeploymentBucketName: appsync-demo-dev-serverlessdeploymentbucket-u48ln3fiu
appsync endpoints:
  graphql: https://s6ghsxmtbnfaxperetsottu.appsync-api.us-west-1.amazonaws.com/graphql
  realtime: wss://s6ghsxmtbnfaxpp2u4metsottu.appsync-realtime-api.us-west-1.amazonaws.com/graphql
appsync api keys:
  da2-gihxmtd34bf2ncouh2nseu (dev API key)
Enter fullscreen mode Exit fullscreen mode

Go to the https://studio.apollographql.com/sandbox/explorer?referrer=docs-nav, paste graphqlurl in top.
And add header x-api-key: da2-gihxmtd34bf2ncouh2nseu to the headers sections. You are ready to request appsync

Top comments (0)