Amplify AppSync - AWS X-Ray Integration
Tags: aws, xray, appsync, amplify
Published: 2020-02-09 16:13:49

---
title: Amplify AppSync - AWS X-Ray Integration
published: true
description: AWS AppSync is a highly flexible API service backed with GraphQL. Recently X-Ray support was launched for AppSync, so we go through the setup process and some general usage patterns for this excellent service.
canonical_url: https://devopstar.com/2020/02/08/amplify-xray-appsync-integration
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/d7cevu9dfj5homvxdhep.jpg
tags: aws, xray, appsync, amplify
---

*This post was originally written on [DevOpStar](https://devopstar.com/)*. Check it out [here](https://devopstar.com/2020/02/08/amplify-xray-appsync-integration)

[AWS AppSync](https://aws.amazon.com/appsync/) is an AWS Service which simplifies development by exposing a flexible [GraphQL api](https://graphql.org/) that can front a variety of backend data sources.

This week a powerful service called [AWS X-Ray](https://aws.amazon.com/xray/) was integrated natively into AppSync that gives customers the ability to trace requests through their stack.

In this post we will very briefly enable this service on a sample AppSync backed app using [Amplify Framework](https://aws-amplify.github.io/) to demonstrate its power.

### Sample Project

To help get started with AppSync we will be using Amplify Framework; mainly due to its very low barrier to entry and overall flexibility for creating application stacks.

> **NOTE**: I've provided a complete version of the project on [t04glovern/amplify-xray-demo](https://github.com/t04glovern/amplify-xray-demo)

To get started, [install the Amplify CLI](https://aws-amplify.github.io/docs/) and configure it for use on your system. This can be achieved with the following commands

```bash
npm install -g @aws-amplify/cli
amplify configure
```

Although not required we will be using a React app to front our AppSync API. Run the following commands to setup a brand new React project with Amplify dependencies pre-installed.

```bash
# Create React App
npx create-react-app amplify-xray-demo && cd amplify-xray-demo/
npm install aws-amplify aws-amplify-react
```

#### Amplify Init

Now we're going to initialize a new Amplify app within the context of our React app. This is done by running `amplify init` then selecting the options based on your requirements. Below is a list of options I selected

```bash
amplify init
```

* **Enter a name for the project**: amplify-xray-demo
* **Enter a name for the environment**: dev
* **Choose your default editor**: Visual Studio Code
* **Choose the type of app that you're building**: javascript
* **Please tell us about your project**: whatever you want
* **What javascript framework are you using**: react
* **Source Directory Path**: src
* **Distribution Directory Path**: build
* **Build Command**: npm run-script build
* **Start Command**: npm run-script start

#### Amplify Add Api

With the project initialized it's time to add a new AppSync API to the project. This is done by running `amplify add api` and then selecting the options below:

```bash
amplify add api
```

* **Please select from one of the below mentioned services**: GraphQL
* **Provide API name**: todo
* **Choose the default authorization type for the API**: API key
* **Enter a description for the API key**: whatever you want
* **After how many days from now the API key should expire (1-365)**: 7
* **Do you want to configure advanced settings for the GraphQL API**: No, I am done.
* **Do you have an annotated GraphQL schema?**: No
* **Do you want a guided schema creation?**: Yes
* **What best describes your project**: Single object with fields (e.g., “Todo” with ID, name, description)
* **Do you want to edit the schema now?**: Yes

> You will be prompted to edit the schema file, don't worry about editing the file; just press enter to continue on the terminal. The schema will looks like the example below

```graphql
type Todo @model {
  id: ID!
  name: String!
  description: String
}
```

#### Amplify Push

Finally, we're good to push the environment and expose our API! This is done by running `amplify push` with. You with be asked a couple questions that can be answered as follows

```bash
amplify push
# Current Environment: dev

# | Category | Resource name | Operation | Provider plugin   |
# | -------- | ------------- | --------- | ----------------- |
# | Api      | todo          | Create    | awscloudformation |
```

* **Are you sure you want to continue?**: Yes
* **Do you want to generate code for your newly created GraphQL API**: Yes
* **Choose the code generation language target**: javascript
* **Enter the file name pattern of graphql queries, mutations and subscriptions**: src/graphql/\*\*/*.js
* **Do you want to generate/update all possible GraphQL operations - queries, mutations and subscriptions**: Yes
* **Enter maximum statement depth [increase from default if your schema is deeply nested]**: 2

#### React App Code

Once the app finishes pushing you'll have a lot more files in the project folder. specifically there is a file called `aws-exports` with all the API configuration pre-populated for you. With this in mind we can build out an extremely simple notes app (heavily based on the [example for React on the Amplify website](https://aws-amplify.github.io/docs/js/react)).

Change the code in `src/App.js` to be the following:

```js
import React, { Component }  from 'react';
import Amplify, { API, graphqlOperation } from 'aws-amplify';
import awsconfig from './aws-exports';

Amplify.configure(awsconfig);

const listTodos = `query listTodos {
  listTodos{
    items{
      id
      name
      description
    }
  }
}`;

const addTodo = `mutation createTodo($name:String! $description: String!) {
  createTodo(input:{
    name:$name
    description:$description
  }){
    id
    name
    description
  }
}`;

class App extends Component {

  todoMutation = async () => {
    const todoDetails = {
      name: 'Party tonight!',
      description: 'Amplify CLI rocks!'
    };

    const newTodo = await API.graphql(graphqlOperation(addTodo, todoDetails));
    alert(JSON.stringify(newTodo));
  };

  listQuery = async () => {
    console.log('listing todos');
    const allTodos = await API.graphql(graphqlOperation(listTodos));
    alert(JSON.stringify(allTodos));
  };

  render() {
    return (
      <div className="App">
        <button onClick={this.listQuery}>GraphQL Query</button>
        <button onClick={this.todoMutation}>GraphQL Mutation</button>
      </div>
    );
  }
}

export default App;
```

You can test the app is working correctly by running the following commands to start a local server

```bash
npm install && npm run start
```

Then open the browser on [http://localhost:3000/](http://localhost:3000/) to view the results. For this example it's extremely simple; as we're just demonstrating how the X-Ray integration works.

> If you'd like to see a far more interesting sample, check out my post [Building a Serverless Resume with AWS Amplify](https://devopstar.com/2019/02/16/building-a-serverless-resume-with-aws-amplify).

### Enabling X-Ray

Let's get down to the main course and enable X-Ray support on our AppSync API. To do this, currently we need to navigate to the [AppSync Console](https://console.aws.amazon.com/appsync/home?region=us-east-1#/apis) and select our `todo-dev` api from the list.

> Hopefully in the future we'll see X-Ray supported by default, or at the very least configurable from Amplify directly.

![AppSync API list](https://dev-to-uploads.s3.amazonaws.com/i/vw6q887nwa8hvj2zti6l.png)

Next select the `Settings` option on the left and enable X-Ray tracing (about halfway down the page). **Make sure you click Save before navigating away!**

![AppSync Enabling X-Ray support](https://dev-to-uploads.s3.amazonaws.com/i/lkete4lzb25s7369rnx9.png)

### Testing X-Ray

To test our X-Ray tracing we need to generate some requests through the API.

> To do this simply launch the web server locally (run `npm run start` if it isn't already started).

Then make some sample requests by clicking `GraphQL Mutation` and clicking away the alert that pops up. Feel free to do this a couple times to generate a couple traces.

![Amplify Web app generating sample traces](https://dev-to-uploads.s3.amazonaws.com/i/fyakh2ydtl928jh529e4.png)

Then click the `GraphQL Query` button to pull back a list of items stored in the TODO app. Again, click away the alert and query a number of times to generate some sample traces.

![Amplify Web app running AppSync queries](https://dev-to-uploads.s3.amazonaws.com/i/eschea6icwplkap6jb45.png)

**Finally**! The fun part, we navigate to the [AWS X-Ray console](https://us-east-1.console.aws.amazon.com/xray/home?region=us-east-1#/traces) and select `Traces` on the left. You will see a list of traces in the bottom panel, each can be identified by a UUID.

![AWS X-Ray Trace list](https://dev-to-uploads.s3.amazonaws.com/i/790suifeg3gleruq0kuw.png)

If you click on one of the traces you will be presented with a lot of details about the request that passed through the system. Each section indicates the flow of the request to another part of the system.

> In the case below we have the AppSync API in-front of a DynamoDB database.

![AWS X-Ray Trace more details](https://dev-to-uploads.s3.amazonaws.com/i/ega23485it5ia5fmx8vg.png)

The next part is a little more difficult to do, but we're going to try to simulate a bunch of requests to view changes in the traces generated by AWS X-Ray. To do this we'll slightly adjust the code in `src/App.js` so that:

* The `todoMutation` has the alert commented out
* A for loop is added to the render block to generate 1000 items

```js
  todoMutation = async () => {
    const todoDetails = {
      name: 'Party tonight!',
      description: 'Amplify CLI rocks!'
    };

    const newTodo = await API.graphql(graphqlOperation(addTodo, todoDetails));
    //alert(JSON.stringify(newTodo));
  };

...

  render() {
    for (let index = 0; index < 1000; index++) {
      this.todoMutation();
    }
    return (
      <div className="App">
        <button onClick={this.listQuery}>GraphQL Query</button>
        <button onClick={this.todoMutation}>GraphQL Mutation</button>
      </div>
    );
  }
```

Start the Web app again and you'll find if you check the background network traffic that you are generating a large number of requests to the AppSync API.

Now to view all the todo entries in bulk (as this generates the most traffic) we have to make a really small change to the `listTodos` query so we explicitly ask for 1000 item limit. This is because by default scan queries are limited to 10.

I also **HIGHLY** recommend changing the preferred output of the `listQuery` to be `console.log()` instead of alert

```javascript
const listTodos = `query listTodos {
  listTodos(limit: 1000) {
    items{
      id
      name
      description
    }
  }
}`;

...

  listQuery = async () => {
    console.log('listing todos');
    const allTodos = await API.graphql(graphqlOperation(listTodos));
    console.log(JSON.stringify(allTodos))
    //alert(JSON.stringify(allTodos));
  };
```

Now check the latest traces in the AWS X-Ray console and you'll find that the execution time to fulfill the request has doubled.

![AWS X-Ray trace with slightly increased request time](https://dev-to-uploads.s3.amazonaws.com/i/oyor3ulk2bij7chx9um2.png)

Clicking the `todo-dev` title in the waterfall trace along the bottom will open a new panel with more details about the request itself.

![AWS X-Ray trace select map item](https://dev-to-uploads.s3.amazonaws.com/i/6izea5wsdgqyrzgisbso.png)

An example of the detailed output can be seen below; you can actually see details on what specific request parameters the query to DynamoDB was making.

![AWS X-Ray trace item extra details](https://dev-to-uploads.s3.amazonaws.com/i/7627wa6oqdpwphyiizzt.png)

### Deleting Project

Deleting an Amplify project is very straight forward and simply requires the following to be run

```bash
amplify delete
```

### Summary

AppSync is a powerful service that helps enable teams to collaborate better when shared data sources are involved. It provides a flexible interface into data through a common pattern. When you tie in this new X-Ray feature you get a service that also provides excellent visibility to the inner-workings of the requests served over your app.

If you have any awesome examples of X-Ray traces at scale, or stories about using AppSync; I'd love to hear about them! Please hit me up on Twitter [@nathangloverAUS](https://twitter.com/nathangloverAUS).