

# Getting started: Creating your first GraphQL API in AWS AppSync
<a name="quickstart"></a>

You can use the AWS AppSync console to configure and launch a GraphQL API. GraphQL APIs generally require three components:

1. **GraphQL schema** - Your GraphQL schema is the blueprint of the API. It defines the types and fields that you can request when an operation is executed. To populate the schema with data, you must connect data sources to the GraphQL API. In this quickstart guide, we'll be creating a schema using a predefined model.

1. **Data sources**- These are the resources that contain the data for populating your GraphQL API. This can be a DynamoDB table, Lambda function, etc. AWS AppSync supports a multitude of data sources to build robust and scalable GraphQL APIs. Data sources are linked to fields in the schema. Whenever a request is performed on a field, the data from the source populates the field. This mechanism is controlled by the resolver. In this quickstart guide, we'll be creating a data source using a predefined model alongside the schema.

1. **Resolvers** - Resolvers are responsible for linking the schema field to the data source. They retrieve the data from the source, then return the result based on what was defined by the field. AWS AppSync supports both JavaScript and VTL for writing resolvers for your GraphQL APIs. In this quickstart guide, the resolvers will be automatically generated based on the schema and the data source. We won't be delving into this in this section.

AWS AppSync supports the creation and configuration of all GraphQL components. When you open the console, you can use the following methods to create your API:

1. Designing a customized GraphQL API by generating it through a predefined model and setting up a new DynamoDB table (data source) to support it.

1. Designing a GraphQL API with a blank schema and no data sources or resolvers.

1. Using a DynamoDB table to import data and generate your schema's types and fields.

1. Using AWS AppSync's WebSocket capabilities and Pub/Sub architecture to develop real-time APIs.

1. Using existing GraphQL APIs (source APIs) to link to a Merged API.

**Note**  
We recommend reviewing the [Designing a schema](designing-your-schema.md#aws-appsync-designing-your-schema) section before working with more advanced tools. These guides will explain simpler examples that you can use conceptually to build more complex applications in AWS AppSync.

AWS AppSync also supports several non-console options to create GraphQL APIs. These include:

1. AWS Amplify

1. AWS SAM

1. CloudFormation

1. The CDK

 The following example will show you how to create the basic components of a GraphQL API using predefined models and DynamoDB.

**Topics**
+ [Launching a schema](schema-launch-start.md)
+ [

# Taking a tour of the AWS AppSync console
](console-tour.md)
+ [Using GraphQL mutations to add data to a DynamoDB table](add-data-with-graphql-mutation.md)
+ [Using GraphQL queries to retrieve data from a DynamoDB table](retrieve-data-with-graphql-query.md)
+ [Supplemental sections](next-steps.md)

# Launching a schema in the AWS AppSync console
<a name="schema-launch-start"></a>

In this example, you will create a `Todo` API that allows users to create `Todo` items for daily chore reminders like *Finish task* or *Pick up groceries*. This API will demonstrate how to use GraphQL operations where the state persists in a DynamoDB table.

Conceptually, there are three major steps to creating your first GraphQL API. You must define the schema (types and fields), attach your data source(s) to your field(s), then write the resolver that handles the business logic. However, the console experience changes the order of this. We will begin by defining how we want our data source to interact with our schema, then define the schema and resolver later.

**To create your GraphQL API**

1. Sign in to the AWS Management Console and open the [AppSync console](https://console.aws.amazon.com/appsync/). 

1. In the **Dashboard**, choose **Create API**.

1. While **GraphQL APIs** is selected, choose **Design from scratch**. Then, choose **Next**.

1. For **API name**, change the prepopulated name to **Todo API**, then choose **Next**.
**Note**  
There are also other options present here, but we won't be using them for this example.

1. In the **Specify GraphQL resources** section, do the following:

   1. Choose **Create type backed by a DynamoDB table now**.
**Note**  
This means we are going to create a new DynamoDB table to attach as a data source.

   1. In the **Model Name** field, enter **Todo**.
**Note**  
Our first requirement is to define our schema. This **Model Name** will be the type name, so what you're really doing is creating a `type` called `Todo` that will exist in the schema:  

      ```
      type Todo {}
      ```

   1. Under **Fields**, do the following:

      1. Create a field named **id**, with the type `ID`, and required set to `Yes`.
**Note**  
These are the fields that will exist within the scope of your `Todo` type. Your field name here will be called `id` with a type of `ID!`:  

         ```
         type Todo {
         	id: ID!
         }
         ```
AWS AppSync supports multiple scalar values for different use cases. 

      1. Using **Add new field**, create four additional fields with the `Name` values set to **name**, **when**, **where**, and **description**. Their `Type` values will be `String`, and the `Array` and `Required` values will both be set to `No`. It will look like this:  
![\[Model information form showing fields for a Todo model with ID, name, when, where, and description.\]](http://docs.aws.amazon.com/appsync/latest/devguide/images/model-information-tutorial.png)
**Note**  
The full type and its fields will look like this:  

         ```
         type Todo {
         	id: ID!
         	name: String
         	when: String
         	where: String
         	description: String
         }
         ```
Because we're creating a schema using this predefined model, it will also be populated with several boilerplate mutations based on the type such as `create`, `delete`, and `update` to help you populate your data source easily.

   1. Under **configure model table**, enter a table name, such as **TodoAPITable**. Set the **Primary Key** to `id`.
**Note**  
We're essentially creating a new DynamoDB table called *TodoAPITable* that will be attached to the API as our primary data source. Our primary key is set to the required `id` field that we defined before this. Note that this new table is blank and doesn't contain anything except for the partition key.

   1. Choose **Next**.

1. Review your changes and choose **Create API**. Wait a moment to let the AWS AppSync service finish creating your API.

You have successfully created a GraphQL API with its schema and DynamoDB data source. To summarize the steps above, we chose to create a completely new GraphQL API. We defined the name of the API, then added our schema definition by adding our first type. We defined the type and its fields, then chose to attach a data source to one of the fields by creating a new DynamoDB table with no data in it.

# Taking a tour of the AWS AppSync console
<a name="console-tour"></a>

Before we add data to our DynamoDB table, we should review the basic features of the AWS AppSync console experience. The AWS AppSync console tab on the left-hand side of the page allows users to easily navigate to any of the major components or configuration options that AWS AppSync provides:

![\[AWS AppSync console navigation menu showing APIs, Todo API options, and Documentation link.\]](http://docs.aws.amazon.com/appsync/latest/devguide/images/explorer-example-5.jpg)


## Schema designer
<a name="schema-designer"></a>

Choose **Schema** to view the schema you just created. If you review the schema's contents, you'll notice that it has already been loaded with a bunch of helper operations to streamline the development process. In the **Schema** editor, if you scroll through the code, you'll eventually reach the model you defined in the previous section:

```
type Todo {
	id: ID!
	name: String
	when: String
	where: String
	description: String
}
```

Your model became the base type that was used throughout your schema. We'll start adding data to our data source using mutations that were automatically generated from this type.

Here are some additional tips and facts about the **Schema** editor:

1. The code editor has linting and error-checking capabilities that you can use when writing your own apps.

1. The right side of the console shows the GraphQL types that have been created and resolvers on different top-level types, such as queries.

1. When adding new types to a schema (for example, `type User {...}`), you can have AWS AppSync provision DynamoDB resources for you. These include the proper primary key, sort key, and index design to best match your GraphQL data access pattern. If you choose **Create Resources** at the top and choose one of these user-defined types from the menu, you can choose different field options in the schema design. We will cover this in the [design a schema](designing-your-schema.md#aws-appsync-designing-your-schema) section.

### Resolver configuration
<a name="resolver-menu"></a>

In the schema designer, the **Resolvers** section contains all of the types and fields in your schema. If you scroll through the list of fields, you'll notice that you can attach resolvers to certain fields by choosing **Attach**. This will open up a code editor in which you can write your resolver code. AWS AppSync supports both VTL and JavaScript runtimes, which can be changed at the top of the page by choosing **Actions**, then **Update Runtime**. At the bottom of the page, you can also create functions that will run several operations in a sequence. However, resolvers are an advanced topic, and we won't be covering that in this section.

## Data sources
<a name="data-sources-designer"></a>

Choose **Data sources** to view your DynamoDB table. By choosing the `Resource` option (if available), you can view your data source's configuration. In our example, this leads to the DynamoDB console. From there, you can edit your data. You can also directly edit some of the data by choosing the data source, then choosing **Edit**. If you ever need to delete your data source, you can choose your data source, then select **Delete**. Lastly, you can create new data sources by choosing **Create data source**, then configuring the name and type. Note that this option is for linking the AWS AppSync service to an existing resource. You still need to create the resource in your account using the relevant service before AWS AppSync recognizes it.

## Queries
<a name="queries-editor"></a>

Choose **Queries** to view your queries and mutations. When we created our GraphQL API using our model, AWS AppSync automatically generated some helper mutations and queries for testing purposes. In the query editor, the left-hand side contains the **Explorer**. This is a list showing all of your mutations and queries. You can easily enable the operations and fields you want to use here by clicking on their name values. This will cause the code to appear automatically in the center part of the editor. Here, you can edit your mutations and queries by modifying values. At the bottom of the editor, you have the **Query Variable** editor that allows you to enter the field values for the input variables of your operations. Choosing **Run** at the top of the editor will bring up a drop-down list to select the query/mutation to run. The output for this run will appear on the right-hand side of the page. Back in the **Explorer** section at the top, you can choose an operation (Query, Mutation, Subscription), then choose the **\$1** symbol to add a new instance of that particular operation. At the top of the page, there will be another drop-down list that contains the authorization mode for your query runs. However, we will not be covering that feature in this section (For more information, see [Security](security-authz.md#aws-appsync-security).).

## Settings
<a name="console-settings"></a>

Choose **Settings** to view some configuration options for your GraphQL API. Here, you can enable some options like logging, tracing, and web application firewall functionality. You can also add new authorization modes to protect your data from unwanted leaks to the public. However, these options are more advanced and will not be covered in this section.

**Note**  
The default authorization mode, `API_KEY`, uses an API key to test the application. This is the base authorization that's given to all newly created GraphQL APIs. We recommend that you use a different method for production. For the sake of the example in this section, we will only use the API key. For more information about the supported authorization methods, see [Security](security-authz.md#aws-appsync-security).

# Using GraphQL mutations to add data to a DynamoDB table in the AWS AppSync console
<a name="add-data-with-graphql-mutation"></a>

Your next step is to add data to your blank DynamoDB table using a GraphQL mutation. Mutations are one of the fundamental operation types in GraphQL. They are defined in the schema and allow you to manipulate data in your data source. In terms of REST APIs, these are very similar to operations like `PUT` or `POST`.

**To add data to your data source**

1. If you haven't already done so, sign in to the AWS Management Console and open the [AppSync console](https://console.aws.amazon.com/appsync/). 

1. Choose your API from the table.

1. In the tab to the left, choose **Queries**.

1. In the **Explorer** tab to the left of the table, you might see several mutations and queries already defined in the query editor:  
![\[Explorer tab showing a dropdown menu with mutation and query options like createTodo and deleteTodo.\]](http://docs.aws.amazon.com/appsync/latest/devguide/images/explorer-example-1.png)
**Note**  
This mutation is actually sitting in your schema as the `Mutation` type. It has the code:  

   ```
   type Mutation {
   	createTodo(input: CreateTodoInput!): Todo
   	updateTodo(input: UpdateTodoInput!): Todo
   	deleteTodo(input: DeleteTodoInput!): Todo
   }
   ```
As you can see, the operations here are similar to what's inside the query editor.

   AWS AppSync automatically generated these from the model we defined earlier. This example will use the `createTodo` mutation to add entries to our *TodoAPITable* table.

1. Choose the `createTodo` operation by expanding it under the `createTodo` mutation:  
![\[Expanded createTodo mutation showing input fields like description, id, name, when, and where.\]](http://docs.aws.amazon.com/appsync/latest/devguide/images/explorer-example-2.png)

   Enable the checkboxes for all of the fields like the picture above.
**Note**  
The attributes you see here are the different modifiable elements of the mutation. Your `input` can be thought of as the parameter of `createTodo`. The various options with checkboxes are the fields that will be returned in the response once an operation is performed.

1. In the code editor in the center of the screen, you'll notice that the operation appears underneath the `createTodo` mutation:

   ```
   mutation createTodo($createtodoinput: CreateTodoInput!) {
     createTodo(input: $createtodoinput) {
       where
       when
       name
       id
       description
     }
   }
   ```
**Note**  
To explain this snippet properly, we must also look at the schema code. The declaration `mutation createTodo($createtodoinput: CreateTodoInput!){}` is the mutation with one of its operations, `createTodo`. The full mutation is located in the schema:  

   ```
   type Mutation {
   	createTodo(input: CreateTodoInput!): Todo
   	updateTodo(input: UpdateTodoInput!): Todo
   	deleteTodo(input: DeleteTodoInput!): Todo
   }
   ```
Going back to the mutation declaration from the editor, the parameter is an object called `$createtodoinput` with a required input type of `CreateTodoInput`. Note that `CreateTodoInput` (and all inputs in the mutation) are also defined in the schema. For example, here's the boilerplate code for `CreateTodoInput`:  

   ```
   input CreateTodoInput {
   	name: String
   	when: String
   	where: String
   	description: String
   }
   ```
It contains the fields we defined in our model, namely `name`, `when`, `where`, and `description`.  
Going back to the editor code, in `createTodo(input: $createtodoinput) {}`, we declare the input as `$createtodoinput`, which was also used in the mutation declaration. We do this because this allows GraphQL to validate our inputs against the provided types and ensure that they are being used with the correct inputs.  
The final part of the editor code shows the fields that will be returned in the response after an operation is performed:  

   ```
   {
       where
       when
       name
       id
       description
     }
   ```

   In the **Query variables** tab below this editor, there will be a generic `createtodoinput` object that may have the following data:

   ```
   {
     "createtodoinput": {
       "name": "Hello, world!",
       "when": "Hello, world!",
       "where": "Hello, world!",
       "description": "Hello, world!"
     }
   }
   ```
**Note**  
This is where we allocate the values for the input mentioned earlier:  

   ```
   input CreateTodoInput {
   	name: String
   	when: String
   	where: String
   	description: String
   }
   ```

   Change the `createtodoinput` by adding information we want to put in our DynamoDB table. In this case, we wanted to create some `Todo` items as reminders:

   ```
   {
     "createtodoinput": {
       "name": "Shopping List",
       "when": "Friday",
       "where": "Home",
       "description": "I need to buy eggs"
     }
   }
   ```

1. Choose **Run** at the top of the editor. Choose **createTodo** in the drop-down list. On the right-hand side of the editor, you should see the response. It may look something like this:

   ```
   {
     "data": {
       "createTodo": {
         "where": "Home",
         "when": "Friday",
         "name": "Shopping List",
         "id": "abcdefgh-1234-1234-1234-abcdefghijkl",
         "description": "I need to buy eggs"
       }
     }
   }
   ```

   If you navigate to the DynamoDB service, you'll now see an entry in your data source with this information:  
![\[TodoAPITable interface showing a completed scan with 1 item returned in a table format.\]](http://docs.aws.amazon.com/appsync/latest/devguide/images/explorer-example-3.png)

To summarize the operation, the GraphQL engine parsed the record, and a resolver inserted it into your Amazon DynamoDB table. Again, you can verify this in the DynamoDB console. Notice that you don’t need to pass in an `id` value. An `id` is generated and returned in the results. This is because the example used an `autoId()` function in a GraphQL resolver for the partition key set on your DynamoDB resources. We will cover how you can build resolvers in a different section. Take note of the returned `id` value; you will use it in the next section to retrieve data with a GraphQL query.

# Using GraphQL queries to retrieve data from a DynamoDB table in the AWS AppSync console
<a name="retrieve-data-with-graphql-query"></a>

Now that a record exists in your database, you'll get results when you run a query. A query is one of the other fundamental operations of GraphQL. It's used to parse and retrieve information from your data source. In terms of REST APIs, this is similar to the `GET` operation. The main advantage of GraphQL queries is the ability to specify your application's exact data requirements so that you fetch the relevant data at the right time. 

**To query your data source**

1. If you haven't already done so, sign in to the AWS Management Console and open the [AppSync console](https://console.aws.amazon.com/appsync/). 

1. Choose your API from the table.

1. In the tab to the left, choose **Queries**.

1. In the **Explorer** tab to the left of the table, under `query` `listTodos`, expand the `getTodo` operation:  
![\[Expanded getTodo operation showing fields id, description, name, when, and where.\]](http://docs.aws.amazon.com/appsync/latest/devguide/images/explorer-example-4.png)

1. In the code editor, you should see the operation code:

   ```
   query listTodos {
     getTodo(id: "") {
       description
       id
       name
       when
       where
     }
   ```

   In `(id:"")`, fill in the value that you saved in the result from the mutation operation. In our example, this would be:

   ```
   query listTodos {
     getTodo(id: "abcdefgh-1234-1234-1234-abcdefghijkl") {
       description
       id
       name
       when
       where
     }
   ```

1. Choose **Run**, then **listTodos**. The result will appear to the right of the editor. Our example looked like this:

   ```
   {
     "data": {
       "getTodo": {
         "description": "I need to buy eggs",
         "id": "abcdefgh-1234-1234-1234-abcdefghijkl",
         "name": "Shopping List",
         "when": "Friday",
         "where": "Home"
       }
     }
   }
   ```
**Note**  
Queries only return the fields you specify. You can deselect the fields you don't need by deleting them from the return field:  

   ```
   {
       description
       id
       name
       when
       where
     }
   ```
You can also uncheck the box in the **Explorer** tab next to the field you want to delete.

1. You can also try the `listTodos` operation by repeating the steps to create an entry in your data source, then repeating the query steps with the `listTodos` operation. Here's an example where we added a second task:

   ```
   {
     "createtodoinput": {
       "name": "Second Task",
       "when": "Monday",
       "where": "Home",
       "description": "I need to mow the lawn"
     }
   }
   ```

   By calling the `listTodos` operation, it returned both the old and new entries:

   ```
   {
     "data": {
       "listTodos": {
         "items": [
           {
             "id": "abcdefgh-1234-1234-1234-abcdefghijkl",
             "name": "Shopping List",
             "when": "Friday",
             "where": "Home",
             "description": "I need to buy eggs"
           },
           {
             "id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
             "name": "Second Task",
             "when": "Monday",
             "where": "Home",
             "description": "I need to mow the lawn"
           }
         ]
       }
     }
   }
   ```

# Supplemental sections for the AWS AppSync console
<a name="next-steps"></a>

These sections are a reference for more advanced AWS AppSync topics. We recommend following the *Supplemental reading* section before doing anything else.

## Integration
<a name="app-integration"></a>

In the console tab, if you choose the name of your API, the **Integration** page appears:

![\[AWS AppSync sidebar menu with APIs, Todo API highlighted, and other options listed.\]](http://docs.aws.amazon.com/appsync/latest/devguide/images/explorer-example-6.png)


It summarizes the steps for setting up your API and outlines the next steps for building a client application. The **Integrate with your app** section provides details for using the [AWS Amplify toolchain](https://aws-amplify.github.io/) to automate the process of connecting your API with iOS, Android, and JavaScript applications through config and code generation. The Amplify toolchain provides full support for building projects from your local workstation including GraphQL provisioning and workflows for CI/CD.

The **Client Samples** section also lists sample client applications (e.g., JavaScript, iOS, Android) for testing an end-to-end experience. You can clone and download these samples, and the configuration file has the necessary information (such as your endpoint URL) you need to get started. Follow the instructions on the [AWS Amplify toolchain](https://aws-amplify.github.io/) page to run your app.

## Supplemental reading
<a name="supplemental-reading-quickstart"></a>
+ [Designing GraphQL APIs with AWS AppSync](designing-a-graphql-api.md) - This is a comprehensive guide for creating your GraphQL using a blank schema with no data sources or resolvers.