AWS AppSync
AWS AppSync Developer Guide

Designing Your Schema

Creating an Empty Schema

Schema files are text files, usually named schema.graphql. You can create this file and submit it to AWS AppSync by using the CLI or navigating to the console and adding the following under the Schema page:

schema { }

Every schema has this root for processing. This fails to process until you add a root query type.

Adding a Root Query Type

For this example, we create a Todo application. A GraphQL schema must have a root query type, so we add a root type named Query with a single getTodos field that returns a list containing Todo objects. Add the following to your schema.graphql file:

schema { query:Query } type Query { getTodos: [Todo] }

Notice that we haven't yet defined the Todo object type. Let's do that now.

Defining a Todo Type

Now, create a type that contains the data for a Todo object:

schema { query:Query } type Query { getTodos: [Todo] } type Todo { id: ID! name: String description: String priority: Int }

Notice that the Todo object type has fields that are scalar types, such as strings and integers. AWS AppSync also has enhanced Scalar types in AWS AppSync in addition to the base GraphQL scalars that you can use in a schema. Any field that ends in an exclamation point is a required field. The ID scalar type is a unique identifier that can be either String or Int. You can control these in your resolver mapping templates for automatic assignment, which is covered later.

There are similarities between the Query and Todo types. In GraphQL, the root types (that is, Query, Mutation, and Subscription) are similar to the ones you define, but they're different in that you expose them from your schema as the entry point for your API. For more information, see The Query and Mutation types.

Adding a Mutation Type

Now that you have an object type and can query the data, if you want to add, update, or delete data via the API you need to add a mutation type to your schema. For the Todo example, add this as a field named addTodo on a mutation type:

schema { query:Query mutation: Mutation } type Query { getTodos: [Todo] } type Mutation { addTodo(id: ID!, name: String, description: String, priority: Int): Todo } type Todo { id: ID! name: String description: String priority: Int }

Note that the mutation is also added to this schema type because it is a root type.

Modifying the Todo Example with a Status

At this point, your GraphQL API is functioning structurally for reading and writing Todo objects--it just doesn't have a data source, which is described in the next section. You can modify this API with more advanced functionality, such as adding a status to your Todo, which comes from a set of values defined as an ENUM:

schema { query:Query mutation: Mutation } type Query { getTodos: [Todo] } type Mutation { addTodo(id: ID!, name: String, description: String, priority: Int, status: TodoStatus): Todo } type Todo { id: ID! name: String description: String priority: Int status: TodoStatus } enum TodoStatus { done pending }

Choose Save Schema.

An ENUM is like a string, but it can take one of a set of values. In the previous example, you added this type, modified the Todo type, and added the Todo field to contain this functionality.

Note: You can skip directly to Attaching a Data Source and begin connecting your schema to a data source now, or keep reading to modify your schema with paginations and relational structure.

Subscriptions

Subscriptions in AWS AppSync are invoked as a response to a mutation. You configure this with a Subscription type and @aws_subscribe() directive in the schema to denote which mutations invoke one or more subscriptions. For more information about configuring subscriptions, see Real-Time Data.

Further Reading

For more information, see the GraphQL type system.

Advanced - Relations and Pagination

Suppose you had a million todos. You wouldn't want to fetch all of these every time, instead you would want to paginate through them. Make the following changes to your schema:

  • To the getTodos field, add two input arguments: limit and nextToken.

  • Add a new TodoConnection type that has todos and nextToken fields.

  • Change getTodos so that it returns TodoConnection (not a list of Todos).

schema { query:Query mutation: Mutation } type Query { getTodos(limit: Int, nextToken: String): TodoConnection } type Mutation { addTodo(id: ID!, name: String, description: String, priority: Int, status: TodoStatus): Todo } type Todo { id: ID! name: String description: String priority: Int status: TodoStatus } type TodoConnection { todos: [Todo] nextToken: String } enum TodoStatus { done pending }

The TodoConnection type allows you to return a list of todos and a nextToken for getting the next batch of todos. Note that it is a single TodoConnection and not a list of connections. Inside the connection is a list of todo items ([Todo]) which gets returned with a pagination token. In AWS AppSync, this is connected to Amazon DynamoDB with a mapping template and automatically generated as an encrypted token. This converts the value of the limit argument to the maxResults parameter and the argument to the exclusiveStartKey parameter. For examples and the built-in template samples in the AWS AppSync console, see Resolver Mapping Template Reference.

Next, suppose your todos have comments, and you want to run a query that returns all the comments for a todo. This is handled through GraphQL connections, as you created in the previous schema. Modify your schema to have a Comment type, add a comments field to the Todo type, and add an addComment field on the Mutation type as follows:

schema { query: Query mutation: Mutation } type Query { getTodos(limit: Int, nextToken: String): TodoConnection } type Mutation { addTodo(id: ID!, name: String, description: String, priority: Int, status: TodoStatus): Todo addComment(todoid: ID!, content: String): Comment } type Comment { todoid: ID! commentid: String! content: String } type Todo { id: ID! name: String description: String priority: Int status: TodoStatus comments: [Comment] } type TodoConnection { todos: [Todo] nextToken: String } enum TodoStatus { done pending }

Choose Save Schema.

Note that the Comment type has the todoid that it's associated with, commentid, and content. This corresponds to a primary key + sort key combination in the Amazon DynamoDB table you create later.

The application graph on top of your existing data sources in AWS AppSync enables you to return data from two separate data sources in a single GraphQL query. In the example, the assumption is that there is both a Todos table and a Comments table. We'll show how to do this in Attaching a Data Source and Configuring Resolvers.