AWS AppSync
AWS AppSync Developer Guide

Building a NodeJS Client App

AWS AppSync integrates with the Apollo GraphQL client for building client applications. AWS provides Apollo plugins for offline support, authorization, and subscription handshaking. This tutorial shows how you can use the AWS AppSync SDK with the Apollo client directly in a Node.js application. You can follow a similar process with popular JavaScript frameworks.

Before You Begin

This tutorial expects a GraphQL schema with the following structure:

schema { query: Query mutation: Mutation subscription: Subscription } type Mutation { addPost(id: ID! author: String! title: String content: String url: String): Post! updatePost(id: ID! author: String! title: String content: String url: String ups: Int! downs: Int! expectedVersion: Int!): Post! deletePost(id: ID!): Post! } type Post { id: ID! author: String! title: String content: String url: String ups: Int downs: Int version: Int! } type Query { allPost: [Post] getPost(id: ID!): Post } type Subscription { newPost: Post @aws_subscribe(mutations:["addPost"]) }

This schema is from the DynamoDB resolvers tutorial, with a subscription added. To follow the complete flow, you can optionally walk through that tutorial first. If you would like to do more customization of GraphQL resolvers, such as those that use DynamoDB, see the Resolver Mapping Template Reference.

Get the GraphQL API Endpoint

After you create your GraphQL API, you'll need to get the API endpoint (URL) so you can use it in your client application. You can get the API endpoint in either of the following ways:

  • In the AWS AppSync console, choose Home, and then choose GraphQL URL to see the API endpoint.

  • Run the following CLI command:

aws appsync get-graphql-api --api-id $GRAPHQL_API_ID

The following instructions show how you can use AWS_IAM for client authorization. In the console, select Settings on the left, and then click AWS_IAM.

Create a Client Application

Create a new project and initialize it with npm, accepting the defaults, as follows:

mkdir appsync && cd appsync touch index.js aws-exports.js npm init

AWS AppSync supports several authorization types, which you can learn more about in Security. We recommend using short-term credentials from Amazon Cognito Federated Identities or Amazon Cognito user pools. For example purposes, we show how you can use IAM keys. Your aws-exports file should look like the following:

"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var config = { AWS_ACCESS_KEY_ID: '', AWS_SECRET_ACCESS_KEY: '', HOST: 'URL.YOURREGION.amazonaws.com', REGION: 'YOURREGION', PATH: '/graphql', ENDPOINT: '', }; config.ENDPOINT = "https://" + config.HOST + config.PATH; exports.default = config;

Edit your package.json dependencies file and be sure it includes the following:

"dependencies": { "apollo-cache-inmemory": "^1.1.0", "apollo-client": "^2.0.3", "apollo-link": "^1.0.3", "apollo-link-http": "^1.2.0", "aws-sdk": "^2.141.0", "aws-appsync": "^1.0.0", "es6-promise": "^4.1.1", "graphql": "^0.11.7", "graphql-tag": "^2.5.0", "isomorphic-fetch": "^2.2.1", "ws": "^3.3.1" }

From a command line, run the following:

npm install

Now add the following code to your index.js file:

Note: If you're using this sample in an AWS Lambda function you must uncomment and use the client.query({ query: query, fetchPolicy: 'network-only' }) statement.

"use strict"; /** * This shows how to use standard Apollo client on Node.js */ global.WebSocket = require('ws'); global.window = global.window || { setTimeout: setTimeout, clearTimeout: clearTimeout, WebSocket: global.WebSocket, ArrayBuffer: global.ArrayBuffer, addEventListener: function () { }, navigator: { onLine: true } }; global.localStorage = { store: {}, getItem: function (key) { return this.store[key] }, setItem: function (key, value) { this.store[key] = value }, removeItem: function (key) { delete this.store[key] } }; require('es6-promise').polyfill(); require('isomorphic-fetch'); // Require exports file with endpoint and auth info const aws_exports = require('./aws-exports').default; // Require AppSync module const AUTH_TYPE = require('aws-appsync/lib/link/auth-link').AUTH_TYPE; const AWSAppSyncClient = require('aws-appsync').default; const url = aws_exports.ENDPOINT; const region = aws_exports.REGION; const type = AUTH_TYPE.AWS_IAM; // If you want to use API key-based auth const apiKey = 'xxxxxxxxx'; // If you want to use a jwtToken from Amazon Cognito identity: const jwtToken = 'xxxxxxxx'; // If you want to use AWS... const AWS = require('aws-sdk'); AWS.config.update({ region: aws_exports.REGION, credentials: new AWS.Credentials({ accessKeyId: aws_exports.AWS_ACCESS_KEY_ID, secretAccessKey: aws_exports.AWS_SECRET_ACCESS_KEY }) }); const credentials = AWS.config.credentials; // Import gql helper and craft a GraphQL query const gql = require('graphql-tag'); const query = gql(` query AllPosts { allPost { __typename id title content author version } }`); // Set up a subscription query const subquery = gql(` subscription NewPostSub { newPost { __typename id title author version } }`); // Set up Apollo client const client = new AWSAppSyncClient({ url: url, region: region, auth: { type: type, credentials: credentials, } }); client.hydrated().then(function (client) { //Now run a query client.query({ query: query }) //client.query({ query: query, fetchPolicy: 'network-only' }) //Uncomment for AWS Lambda .then(function logData(data) { console.log('results of query: ', data); }) .catch(console.error); //Now subscribe to results const observable = client.subscribe({ query: subquery }); const realtimeResults = function realtimeResults(data) { console.log('realtime data: ', data); }; observable.subscribe({ next: realtimeResults, complete: console.log, error: console.log, }); });

If you want to use an API key or Amazon Cognito user pools in the previous example, you could update the AUTH_TYPE as follows:

const type = AUTH_TYPE.API_KEY const type = AUTH_TYPE.AMAZON_COGNITO_USER_POOLS

You need to provide the key or JWT token, as appropriate.