Amplify has re-imagined the way frontend developers build fullstack applications. Develop and deploy without the hassle.

Define your model types

You are currently viewing the legacy GraphQL Transformer documentation. View latest documentation

@model

Object types that are annotated with @model are top-level entities in the generated API. Objects annotated with @model are stored in Amazon DynamoDB and are capable of being protected via @auth, related to other objects via @connection, and streamed into Amazon OpenSearch via @searchable. You may also apply the @versioned directive to instantly add a version field and conflict detection to a model type.

Definition

The following SDL defines the @model directive that allows you to easily define top level object types in your API that are backed by Amazon DynamoDB.

directive @model(
queries: ModelQueryMap
mutations: ModelMutationMap
subscriptions: ModelSubscriptionMap
timestamps: TimestampConfiguration
) on OBJECT
input ModelMutationMap {
create: String
update: String
delete: String
}
input ModelQueryMap {
get: String
list: String
}
input ModelSubscriptionMap {
onCreate: [String]
onUpdate: [String]
onDelete: [String]
level: ModelSubscriptionLevel
}
enum ModelSubscriptionLevel {
off
public
on
}
input TimestampConfiguration {
createdAt: String
updatedAt: String
}

Usage

Define a GraphQL object type and annotate it with the @model directive to store objects of that type in DynamoDB and automatically configure CRUDL queries and mutations.

type Post @model {
id: ID! # id: ID! is a required attribute.
title: String!
tags: [String!]!
}

You may also override the names of any generated queries, mutations and subscriptions, or remove operations entirely.

type Post
@model(queries: { get: "post" }, mutations: null, subscriptions: null) {
id: ID!
title: String!
tags: [String!]!
}

This would create and configure a single query field post(id: ID!): Post and no mutation fields.

Model directive automatically adds createdAt and updatedAt timestamps to each entities. The timestamp field names can be changed by passing timestamps attribute to the directive

type Post
@model(timestamps: { createdAt: "createdOn", updatedAt: "updatedOn" }) {
id: ID!
title: String!
tags: [String!]!
}

The above schema will generate Post with createdOn and updatedOn fields as shown

type Post {
id: ID!
title: String!
tags: [String!]!
createdOn: AWSDateTime!
updatedOn: AWSDateTime!
}

The automatically added createdAt and updatedAt fields can't be set in create or update mutation. If these fields need to be controlled as part of the mutation, they should be in the input schema and should have AWSDateTime as their type

type Post @model {
id: ID!
title: String!
tags: [String!]!
createdAt: AWSDateTime!
updatedAt: AWSDateTime!
}

Generates

A single @model directive configures the following AWS resources:

  • An Amazon DynamoDB table with PAY_PER_REQUEST billing mode enabled by default.
  • An AWS AppSync DataSource configured to access the table above.
  • An AWS IAM role attached to the DataSource that allows AWS AppSync to call the above table on your behalf.
  • Up to 8 resolvers (create, update, delete, get, list, onCreate, onUpdate, onDelete) but this is configurable via the queries, mutations, and subscriptions arguments on the @model directive.
  • Input objects for create, update, and delete mutations.
  • Filter input objects that allow you to filter objects in list queries and connection fields.
  • For list queries the default number of objects returned is 100. You can override this behavior by setting the limit argument.

This input schema document

type Post @model {
id: ID!
title: String
metadata: MetaData
}
type MetaData {
category: Category
}
enum Category {
comedy
news
}

would generate the following schema parts

type Post {
id: ID!
title: String!
metadata: MetaData
createdAt: AWSDatetime
updatedAt: AWSDateTime
}
type MetaData {
category: Category
}
enum Category {
comedy
news
}
input MetaDataInput {
category: Category
}
enum ModelSortDirection {
ASC
DESC
}
type ModelPostConnection {
items: [Post]
nextToken: String
}
input ModelStringFilterInput {
ne: String
eq: String
le: String
lt: String
ge: String
gt: String
contains: String
notContains: String
between: [String]
beginsWith: String
}
input ModelIDFilterInput {
ne: ID
eq: ID
le: ID
lt: ID
ge: ID
gt: ID
contains: ID
notContains: ID
between: [ID]
beginsWith: ID
}
input ModelIntFilterInput {
ne: Int
eq: Int
le: Int
lt: Int
ge: Int
gt: Int
contains: Int
notContains: Int
between: [Int]
}
input ModelFloatFilterInput {
ne: Float
eq: Float
le: Float
lt: Float
ge: Float
gt: Float
contains: Float
notContains: Float
between: [Float]
}
input ModelBooleanFilterInput {
ne: Boolean
eq: Boolean
}
input ModelPostFilterInput {
id: ModelIDFilterInput
title: ModelStringFilterInput
and: [ModelPostFilterInput]
or: [ModelPostFilterInput]
not: ModelPostFilterInput
}
type Query {
getPost(id: ID!): Post
listPosts(
filter: ModelPostFilterInput
limit: Int
nextToken: String
): ModelPostConnection
}
input CreatePostInput {
title: String!
metadata: MetaDataInput
}
input UpdatePostInput {
id: ID!
title: String
metadata: MetaDataInput
}
input DeletePostInput {
id: ID
}
type Mutation {
createPost(input: CreatePostInput!): Post
updatePost(input: UpdatePostInput!): Post
deletePost(input: DeletePostInput!): Post
}
type Subscription {
onCreatePost: Post @aws_subscribe(mutations: ["createPost"])
onUpdatePost: Post @aws_subscribe(mutations: ["updatePost"])
onDeletePost: Post @aws_subscribe(mutations: ["deletePost"])
}