AWS AppSync
AWS AppSync Developer Guide

(Optional) Import from Amazon DynamoDB

AWS AppSync can automatically create a GraphQL schema and connect resolvers to existing Amazon DynamoDB tables. This can be useful if you have DynamoDB tables that you want to expose data through a GraphQL endpoint, or if you're more comfortable starting first with your database design instead of a GraphQL schema.

Import a DynamoDB Table

From the AWS AppSync console, go to the Data Sources page, choose New, enter a friendly name for your data source, and then choose Amazon DynamoDB as the data source type. Choose the appropriate table, and then choose Automatically generate GraphQL.

The following two code editors with the GraphQL schema appear:

  • Top editor - You can use this editor to give your type a custom name (such as type MYNAME {...}), which will contain the data from your DynamoDB table when you run queries or mutations. You can also add fields to the type, such as DynamoDB non-key attributes (which cannot be detected on import).

  • Bottom editor - Use this read-only editor to review generated GraphQL schema snippets. It shows what types, queries, and mutations will be merged into your schema. If you edit the type in the top editor, the bottom editor changes as appropriate.

Choose Create. Your schema is merged and resolvers are created. After this is complete, you can run mutations and queries as described in Using Your API.

Note: A GraphQL input type is created for the arguments of the created schema. For example, if you import a table called Books, there might be an input type like the following:

input CreateBooksInput { ISBN: String! Author: String Title: String Price: String }

To use this in a GraphQL query or mutation, do the following:

mutation add { createBooks(input:{ ISBN:2349238 Author:"Nadia Bailey" Title:"Running in the park" Price:"10" }){ ISBN Author } }

Example Schema from Import

Suppose that you have a DynamoDB table with the following format:

{ Table: { AttributeDefinitions: [ { AttributeName: 'authorId', AttributeType: 'S' }, { AttributeName: 'bookId', AttributeType: 'S' }, { AttributeName: 'title', AttributeType: 'S' } ], TableName: 'BookTable', KeySchema: [ { AttributeName: 'authorId', KeyType: 'HASH' }, { AttributeName: 'title', KeyType: 'RANGE' } ], TableArn: 'arn:aws:dynamodb:us-west-2:012345678910:table/BookTable', LocalSecondaryIndexes: [ { IndexName: 'authorId-bookId-index', KeySchema: [ { AttributeName: 'authorId', KeyType: 'HASH' }, { AttributeName: 'bookId', KeyType: 'RANGE' } ], Projection: { ProjectionType: 'ALL' }, IndexSizeBytes: 0, ItemCount: 0, IndexArn: 'arn:aws:dynamodb:us-west-2:012345678910:table/BookTable/index/authorId-bookId-index' } ], GlobalSecondaryIndexes: [ { IndexName: 'title-authorId-index', KeySchema: [ { AttributeName: 'title', KeyType: 'HASH' }, { AttributeName: 'authorId', KeyType: 'RANGE' } ], Projection: { ProjectionType: 'ALL' }, IndexArn: 'arn:aws:dynamodb:us-west-2:012345678910:table/BookTable/index/title-authorId-index' } ] } }

The type editor at the top shows the following:

type Book { # Key attributes. Changing these may result in unexpected behavior. authorId: String! title: String! # Index attributes. Changing these may result in unexpected behavior. bookId: String # Add additional non-key attributes below. isPublished: Boolean }

This top editor is writable, and you need to add the non-key attributes shown in the bottom editor (for example, like isPublished) manually because they can't be inferred from DynamoDB automatically. For example, if you had another attribute on an item in your DynamoDB table called rating, you need to add it under isPublished to have it populated in the GraphQL schema. In this example, the bottom editor would have the following proposed schema merges:

type Query { getBook(authorId: ID!, title: String!): Book listBooks(first: Int, after: String): BookConnection getBookByAuthorIdBookIdIndex(authorId: ID!, bookId: ID!): Book queryBooksByAuthorIdBookIdIndex(authorId: ID!, first: Int, after: String): BookConnection getBookByTitleAuthorIdIndex(title: String!, authorId: ID!): Book queryBooksByTitleAuthorIdIndex(title: String!, first: Int, after: String): BookConnection } type Mutation { createBook(input: CreateBookInput!): Book updateBook(input: UpdateBookInput!): Book deleteBook(input: DeleteBookInput!): Book } type Subscription { onCreateBook(authorId: ID, title: String, bookId: ID, isPublished: Boolean): Book @aws_subscribe(mutations: ["createBook"]) onUpdateBook(authorId: ID, title: String, bookId: ID, isPublished: Boolean): Book @aws_subscribe(mutations: ["updateBook"]) onDeleteBook(authorId: ID, title: String, bookId: ID, isPublished: Boolean): Book @aws_subscribe(mutations: ["deleteBook"]) } input CreateBookInput { authorId: ID! title: String! bookId: ID! isPublished: Boolean } input UpdateBookInput { authorId: ID! title: String! bookId: ID isPublished: Boolean } input DeleteBookInput { authorId: ID! title: String! } type BookConnection { items: [Book] nextToken: String }