Part 2: AppSync Backend: AWS Managed GraphQL Service ----------------------------------------------------  AWS AppSync architecture > **Part 1**: [Introduction: GraphQL endpoints with API Gateway + AWS Lambda](https://serverless.com/blog/running-scalable-reliable-graphql-endpoint-with-serverless/) > **Part 2**: AppSync Backend: [AWS](https://hackernoon.com/tagged/aws) Managed GraphQL Service (this post) > **Part 3**: [AppSync Frontend: AWS Managed GraphQL Service](https://hackernoon.com/running-a-scalable-reliable-graphql-endpoint-with-serverless-db16e42dc266) > **Part 4**: [Serverless AppSync Plugin: New Features](https://hackernoon.com/serverless-appsync-plugin-top-10-new-features-3faaf6789480) (Latest!!!) > “Powering your GraphQL endpoint with a serverless backend solves scaling and availability concerns outright, and it gives you a big leg up on security. It’s not even that much code or configuration”. - Part 1 ### Introduction In this part of the series, we will learn how to build [GraphQL](https://hackernoon.com/tagged/graphql) endpoints with new AWS service called — **_AppSync_** [launched at the re: Invent 2017](https://aws.amazon.com/blogs/aws/introducing-amazon-appsync/). I will be creating a backend for a **_mini Twitter App_** using AppSync with DynamoDB, ElasticSearch, and AWS Lambda integrations and show you how to configure and deploy AppSync using _new_ [**Serverless-AppSync-Plugin**](https://github.com/sid88in/serverless-appsync-plugin)**.** Let’s get started! 🏃 > _Note: If you are new to Serverless or GraphQL, I would recommend grabbing a cup of coffee and going through_ [**_Part 1_**](https://serverless.com/blog/running-scalable-reliable-graphql-endpoint-with-serverless/) _of this series, then come back._ ### What is AppSync? AWS AppSync is a fully managed serverless [GraphQL](http://graphql.org/) service for real-time data queries, synchronization, communications and offline programming features. This blog covers creating a GraphQL API itself, and next part of this series will focus on the AppSync Client and its features _(_[_stay tuned_](https://twitter.com/sidg_sid)_!_ 🔈_)._ “_It turns out that_ [_Apollo Client 2.0_](https://dev-blog.apollodata.com/apollo-client-2-0-beyond-graphql-apis-888807b53afe)_’s modular architecture was a huge win for developers looking to customize their GraphQL client because that’s exactly how the AWS team was able to build_ [_AppSync Client_](https://github.com/awslabs/aws-mobile-appsync-sdk-js/blob/254930e3de1211c20bbac3efadf571008826bc32/packages/aws-appsync/src/client.js)_!_” — by [Peggy Rayzis](https://medium.com/@peggyrayzis) > _Note: This_ [_post_](https://hackernoon.com/aws-appsync-up-and-running-560a42d96ba7?gi=6808eedc7c55) _by_ [_Nader Dabit_](https://medium.com/@dabit3) _is an excellent read for an AppSync primer._ ### AppSync vs. GraphQL + Lambda > If Serverless + Lambda + GraphQL works so well, then why even bother exploring other solutions? > Because AppSync has a cool piece of functionality that GraphQL + Lambda doesn’t. Namely: real-time subscriptions. Both have their advantages. But which one is right for your application? **_Use Lambda_** when you want to have more control over what the endpoint does. For example, maybe you want to use your favorite Lambda Server to handle client requests; or perhaps you need a more closed system, and you don’t want to use AWS authentication systems. **_Use AppSync_** when you need support for real-time updates which scales to millions of people. It is much easier to do as compared to [implementing real time updates with Lambda and IoT](https://serverless.com/blog/realtime-updates-using-lambda-websockets-iot/). And of course, it comes with fully AWS managed GraphQL service and enterprise-level security features. ### How can I get started with AppSync in Production? I am glad you asked! After working with AppSync, you may quickly realize that it is quite time-consuming and error-prone to wire up the entire backend components including GraphQL Schema, Resolver Mapping Templates and Data Sources (as I’ll explain further in a minute). In a production environment, you would want a piece of code or configuration to make your deployment fully automated along with being fast and scalable. > For the same reason, I am happy to announce brand new [Serverless-AppSync-Plugin](https://github.com/sid88in/serverless-appsync-plugin) which allows you to deploy AppSync Components via Serverless CLI and is now open sourced 🎉 > My motivation behind writing this blog is to share my learnings about AppSync and provide a smooth and more flexible way to stand up a GraphQL endpoint in production within seconds. > _Note: Examples covered in this blog are available on_ [_GitHub_](https://github.com/serverless/serverless-graphql/tree/master/app-backend/appsync)_._ ### Let’s build a GraphQL Endpoint with AppSync Plugin Before jumping into this, let me explain AppSync’s **_four_** building blocks: 1. **GraphQL Schema** Complete schema of the _mini Twitter app_ is available [here](https://github.com/serverless/serverless-graphql/blob/master/app-backend/appsync/dynamo-elasticsearch-lambda/schema.graphql). It includes various types and fields to retrieve user and tweet info. 2. **GraphQL Resolvers (Mapping Templates)** Each field in the schema is resolved using request and response [mapping templates](https://github.com/serverless/serverless-graphql/tree/master/app-backend/appsync/dynamo-elasticsearch-lambda/mapping-templates) (written in [Velocity Templating Language](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-programming-guide.html)). These templates parse the incoming request and interpret responses from your database. 3. **Data Sources** You get built-in support of DynamoDB, ElasticSearch, and Lambda. In fact, Lambda provides flexibility to add RDS, REST API, MongoDB, Druid, etc. 4. **Authentication and IAM Permissions **You can authenticate your API using API KEY, Cognito User Pools along with providing fine-grained access controls using IAM permissions. #### Anatomy of the AppSync SDK: To create the endpoint you basically have two options 1) manually wire all the components together and generate the API in AppSync UI which is **time-consuming and error-prone** or 2) write code using AWS-SDK which **adds more complexity to the entire process**. Here are the series of steps required to have an endpoint up and running:  Anatomy of the AppSync SDK #### Serverless AppSync Plugin to the Rescue And now, look at this 😏 plugins: - serverless-appsync-plugin provider: name: aws runtime: nodejs6.10 custom: appSync: name: # Your GraphQL API Name authenticationType: **AMAZON\_COGNITO\_USER\_POOLS | API KEY** mappingTemplates: - dataSource: **myDynamoDB | myElasticSearch | myLambda** type: # GraphQL Type field: # Schema Field request: # Request Mapping Template response: # Response Mapping Template schema: schema.graphql # Input GraphQL Schema dataSources: - type: **AMAZON\_DYNAMODB | AMAZON\_ELASTICSEARCH | AWS\_LAMBDA** name: **myDynamoDB | myElasticSearch | myLambda** config: **tableName** | **endpoint** | **lambdaFunctionArn** serviceRoleArn: _IAM ROLE_ The Serverless AppSync Plugin allows you to configure all the **_six steps_** as a configuration in your [_serverless.yml_](https://github.com/serverless/serverless-graphql/blob/master/app-backend/appsync/dynamo-elasticsearch-lambda/serverless.yml#L31). You can basically deploy, update or delete AppSync components using these _three_ commands: **serverless deploy-appsync serverless update-appsync serverless delete-appsync** > **_Note_**_: All the configurations in the plugin are self-explanatory, but if you have any questions or want to contribute,_ [_please feel free to reach out to me_](https://twitter.com/sidg_sid)_._ #### Finally, this is how it looks:  AppSync Deployment with Serverless Plugin ### Mini Twitter App Architecture Now, you might be thinking “what is this fuss about mini Twitter App? How does it work? I still don’t get it!”. OK, let me explain: This app consists of a React Frontend along with an AppSync Client integration. You can further simplify the user authentication flow using [AWS Amplify](https://github.com/aws/aws-amplify) and Cognito User Pool (I’ll be covering frontend architecture in detail in my **next** blog post). For the app backend, the GraphQL API is created using the _Serverless AppSync Plugin_. This API connects to DynamoDB (to get user Info), ElasticSearch (to retrieve user tweets) and Lambda (to fetch any additional user info from the Twitter REST API). > Note: Please follow [these instructions](https://github.com/serverless/serverless-graphql#setup-for-production-deploy-resources-to-aws) to run the app in your local environment.  Mini Twitter App Architecture Let’s look at some resolver mapping templates: > _Example 1:_ getUserInfo(handle: String!) _vs._ meInfo Request Mapping Template for _getUserInfo_: { "version" : "2017-02-28", "operation" : "**Query**", "query" : { "expression": "handle = :**handle**", "expressionValues" : { ":handle" : { "S" : "${**context.arguments.handle**}" } } } } Request Mapping Template for _meInfo_: { "version" : "2017-02-28", "operation" : "**Query**", "query" : { "expression": "handle = :**handle**", "expressionValues" : { ":handle" : { "S" : "${**context.identity.username**}" } } } } In this example, the request templates are using DynamoDB Query operation to fetch data from the Users table. In _meInfo_ user’s handle is derived from context variable which contains his identity information (parsed through JWT token on the client side). [This article](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference.html) explains more about the power of context variable and util functions in AppSync. Response Mapping Template for both fields: $util.toJson(**$context.result.items\[0\]**) > _Example 2:_ favourites\_count In this case, we want to fetch the value of a user’s favourite count from Twitter itself. AWS Lambda provides the flexibility to do this by querying the REST API ([reference](https://github.com/serverless/serverless-graphql/blob/master/app-backend/appsync/dynamo-elasticsearch-lambda/handler.js#L6)) **exports**.graphqlHandler = (event, context, callback) => { **switch** (event.**field**) { **case 'favourites\_count'**: { **const** handle = event.**arguments**.**handle** ? event.**arguments**.**handle** : event.**handle**; _getFavouritesCount_(handle).then(result => { callback(**null**, result); }); **break**; } } }; > _Example 3:_ **tweets**(limit: Int!, nextToken: String) ElasticSearch provides an immense power of a search engine. In this case, we have indexd all the tweets in ES and the request mapping template below paginates through the user’s tweets: { "version":"2017-02-28", "operation":"GET", "path":"/user/twitter/\_search", "params":{ "body":{ "from": **$context.arguments.nextToken**, "size": **$context.arguments.limit**, "query" : { "bool" : { "must" : \[ { "match" : { "handle" : **$context.source.handle** } } \] } } } } } Response Mapping Template: { #set($hitcount = **$context.result.hits.total**) #set($tweetList = \[\]) #set($counter = 0) #if($hitcount > 0) #foreach($entry in **$context.result.hits.hits**) #set( $element = ${tweetList.add( { "tweet" : "$entry.get('\_source')\['tweet'\]", "tweet\_id": "$entry.get('\_id')", "created\_at": $entry.get('\_source')\['created\_at'\] })}) #set ($counter = $counter + 1) #end "items" : $util.toJson($tweetList), "nextToken" : "$counter" #end } **Sample GraphQL Query**: **query** { **meInfo**{ _\# DynamoDB_ name description **favourites\_count** _#_ _Lambda_ **tweets**(limit:4, nextToken:"3"){ _\# ElasticSearch_ items{ tweet tweet\_id created\_at } nextToken } } } > Last but not the least… > The best part? All you need to get subscriptions working in the backend is to extend your GraphQL schema with 4 lines of code: type Subscription { addTweet: Tweet @aws\_subscribe(mutations: \[“createTweet”\] } This code sets up a **subscription** that listens to every new [_createTweet_](https://github.com/serverless/serverless-graphql/blob/master/app-backend/appsync/dynamo-elasticsearch-lambda/schema.graphql#L4) mutation, and once your client decides to subscribe to this subscription it will get real-time updates (more on this in the next post 😏) ### AppSync Limitations 1. **Steep learning curve **Working with AppSync requires a good amount of understanding of [VTL](http://velocity.apache.org/engine/1.7/vtl-reference.html). For beginners, I would totally recommend [this guide](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-programming-guide.html). But, the good news is that AWS provides a bunch of [helpers and utilities](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference.html) to make our life easier. 2. **Missing GraphQL Info Object **AppSync doesn’t provide [info object](https://blog.graph.cool/graphql-server-basics-demystifying-the-info-argument-in-graphql-resolvers-6f26249f613a) in the context variable for now which limits its functionality regarding integrating with other open source GraphQL frameworks like [Prisma](https://github.com/graphcool/prisma). 3. **Missing support for DynamoDB Batch operations **As of now, AppSync doesn’t support all DynamoDB API’s for instance — BatchGetItem or BatchPutItem AppSync is actively adding capabilities to simplify the serverless GraphQL experience, and I’m looking forward to it. ### What Next? In the next part of this series, I will explain mini Twitter App’s FrontEnd components in detail including **AppSync Client**, **AWS Amplify**, **React Components**, **Mutations** with **Optimistic Response** and **Offline Support**, **Subscriptions**, **Conflict Resolution** etc _(_[_stay tuned_](https://twitter.com/sidg_sid)_!_ 🔈_)._ _The App will look like this:_  ### Special Thanks First of all, BIG THANKS to [Nik Graf](https://medium.com/@nikgraf) for collaborating on this project, being an excellent mentor along with helping with code reviews and implementation. Thanks, [Philipp](https://medium.com/@pmuens), [Jon](https://twitter.com/superpatell), and [LolCoolKat](https://twitter.com/lolcoolkat) for your hard work on AppSync Plugin. AWS Mobile team ([Richard](https://medium.com/@rthrelkeld1980), [Rohan](https://medium.com/@appwiz), [Nader](https://medium.com/@dabit3), [Manuel](https://twitter.com/menyao), and [Michael](https://medium.com/@mikeparisstuff)) for helping out with questions and working closely to resolve issues and bugs. Last but not the least, thanks everyone who is reading this post or encouraged me to write more. **Your support drives me to contribute more** 😃 😍    [Serverless and GraphQL Meetup](https://www.meetup.com/Serverless/events/245690042) at Glassdoor, San Francisco attended by [Graphcool](https://medium.com/@graphcool), [Serverless](https://medium.com/@serverlessinc), [Danielle](https://medium.com/@danimman), [Nik](https://medium.com/@nikgraf), [Rohan](https://medium.com/@appwiz), [Michael](https://medium.com/@mikeparisstuff) I would like to end this blog with one of my favourite quotes — “_The important thing is not to stop questioning. Curiosity has its own reason for existing.” —_ Albert Einstein