Skip to main content

AppSyncApi

The AppSyncApi construct is a higher level CDK construct that makes it easy to create an AppSync GraphQL API. It provides a simple way to define the data sources and the resolvers in your API. And allows you to configure the specific Lambda functions if necessary. See the examples for more details.

Initializer

new AppSyncApi(scope: Construct, id: string, props: AppSyncApiProps)

Parameters

Examples

The AppSyncApi construct is designed to make it easy to get started with, while allowing for a way to fully configure it as well. Let's look at how, through a couple of examples.

Using the minimal config

import { AppSyncApi } from "@serverless-stack/resources";

new AppSyncApi(this, "GraphqlApi", {
graphqlApi: {
schema: "graphql/schema.graphql",
},
dataSources: {
notesDS: "src/notes.main",
},
resolvers: {
"Query listNotes": "notesDS",
"Query getNoteById": "notesDS",
"Mutation createNote": "notesDS",
"Mutation updateNote": "notesDS",
"Mutation deleteNote": "notesDS",
},
});

Note that, the resolver key can have extra spaces in between, they are just ignored.

Auto-creating Lambda data sources

If the data sources are not configured, a Lambda data source is automatically created for each resolver.

new AppSyncApi(this, "GraphqlApi", {
graphqlApi: {
schema: "graphql/schema.graphql",
},
resolvers: {
"Query listNotes": "src/list.main",
"Query getNoteById": "src/get.main",
"Mutation createNote": "src/create.main",
"Mutation updateNote": "src/update.main",
"Mutation deleteNote": "src/delete.main",
},
});

Specifying function props for all the data sources

You can set some function props and have them apply to all the Lambda data sources.

new AppSyncApi(this, "GraphqlApi", {
graphqlApi: {
schema: "graphql/schema.graphql",
},
defaultFunctionProps: {
timeout: 20,
environment: { tableName: "NOTES_TABLE" },
},
dataSources: {
notesDS: "src/notes.main",
},
resolvers: {
"Query listNotes": "notesDS",
"Mutation createNote": "notesDS",
},
});

Note that, you can set the defaultFunctionProps while configuring the function per data source. The function one will just override the defaultFunctionProps.

new AppSyncApi(this, "GraphqlApi", {
graphqlApi: {
schema: "graphql/schema.graphql",
},
defaultFunctionProps: {
timeout: 20,
},
dataSources: {
notesDS: {
handler: "src/notes.main",
timeout: 10,
},
},
resolvers: {
"Query listNotes": "notesDS",
"Mutation createNote": "notesDS",
},
});

So in the above example, the notesDS data source doesn't use the timeout that is set in the defaultFunctionProps. It'll instead use the one that is defined in the function definition (10 seconds).

Similarly, the defaultFunctionProps also applies when the Lambda data sources are auto-created.

new AppSyncApi(this, "GraphqlApi", {
graphqlApi: {
schema: "graphql/schema.graphql",
},
defaultFunctionProps: {
timeout: 20,
},
resolvers: {
"Query listNotes": {
handler: "src/list.main",
timeout: 10,
},
"Mutation createNote": "src/create.main",
},
});

Using multiple data sources

new AppSyncApi(this, "GraphqlApi", {
graphqlApi: {
schema: "graphql/schema.graphql",
},
dataSources: {
notesDS: "src/notes.main",
billingDS: "src/billing.main",
},
resolvers: {
"Query listNotes": "notesDS",
"Mutation createNote": "notesDS",
"Mutation charge": "billingDS",
},
});

Using other data sources

Using DynamoDB data source

import { MappingTemplate } from "@aws-cdk/aws-appsync";

const notesTable = new Table(this, "Notes", {
fields: {
id: TableFieldType.STRING,
},
primaryIndex: { partitionKey: "id" },
});

new AppSyncApi(this, "GraphqlApi", {
graphqlApi: {
schema: "graphql/schema.graphql",
},
dataSources: {
tableDS: { table: notesTable },
},
resolvers: {
"Query listNotes": {
dataSource: "tableDS",
resolverProps: {
requestMappingTemplate: MappingTemplate.dynamoDbScanTable(),
responseMappingTemplate: MappingTemplate.dynamoDbResultList(),
},
},
},
});

Using RDS data source

import { MappingTemplate } from "@aws-cdk/aws-appsync";

new AppSyncApi(this, "GraphqlApi", {
graphqlApi: {
schema: "graphql/schema.graphql",
},
dataSources: {
rdsDS: {
serverlessCluster: cluster,
secretStore: secret,
},
},
resolvers: {
"Query listNotes": {
dataSource: "rdsDS",
resolverProps: {
requestMappingTemplate: MappingTemplate.fromString(`
{
"version": "2018-05-29",
"statements": [
"SELECT * FROM notes"
]
}
`),
responseMappingTemplate: MappingTemplate.fromString(`
$util.rds.toJsonObject($ctx.result)
`),
},
},
},
});

Using HTTP data source

Starting a Step Function execution on the Mutation callStepFunction.

import { MappingTemplate } from "@aws-cdk/aws-appsync";

new AppSyncApi(this, "GraphqlApi", {
graphqlApi: {
schema: "graphql/schema.graphql",
},
dataSources: {
httpDS: {
endpoint: "https://states.amazonaws.com",
options: {
authorizationConfig: {
signingRegion: "us-east-1",
signingServiceName: "states",
},
},
},
},
resolvers: {
"Mutation callStepFunction": {
dataSource: "httpDS",
resolverProps: {
requestMappingTemplate: MappingTemplate.fromFile("request.vtl"),
responseMappingTemplate: MappingTemplate.fromFile("response.vtl"),
},
},
},
});

Adding resolvers

You can also add data sources and resolvers after the API has been created.

Adding data sources and resolvers

const api = new AppSyncApi(this, "GraphqlApi", {
graphqlApi: {
schema: "graphql/schema.graphql",
},
dataSources: {
notesDS: "src/notes.main",
},
resolvers: {
"Query listNotes": "notesDS",
"Mutation createNote": "notesDS",
},
});

api.addDataSources(this, {
billingDS: "src/billing.main",
});

api.addResolvers(this, {
"Mutation charge": "billingDS",
});

Auto-creating Lambda data sources

const api = new AppSyncApi(this, "GraphqlApi", {
graphqlApi: {
schema: "graphql/schema.graphql",
},
resolvers: {
"Query listNotes": "src/list.main",
"Query getNoteById": "src/get.main",
"Mutation createNote": "src/create.main",
},
});

api.addResolvers(this, {
"Mutation updateNote": "src/update.main",
"Mutation deleteNote": "src/delete.main",
});

Lazily adding resolvers

const api = new AppSyncApi(this, "GraphqlApi", {
graphqlApi: {
schema: "graphql/schema.graphql",
},
});

api.addResolvers(this, {
"Query listNotes": "src/list.main",
"Mutation createNote": "src/create.main",
});

Configuring Auth

Using API Key

import * as cdk from "@aws-cdk/core";
import * as appsync from "@aws-cdk/aws-appsync";

new AppSyncApi(this, "GraphqlApi", {
graphqlApi: {
schema: "graphql/schema.graphql",
authorizationConfig: {
defaultAuthorization: {
authorizationType: appsync.AuthorizationType.API_KEY,
apiKeyConfig: {
expires: cdk.Expiration.after(cdk.Duration.days(365)),
},
},
},
},
});

Using Cognito User Pool

import * as appsync from "@aws-cdk/aws-appsync";

new AppSyncApi(this, "GraphqlApi", {
graphqlApi: {
schema: "graphql/schema.graphql",
authorizationConfig: {
defaultAuthorization: {
authorizationType: appsync.AuthorizationType.USER_POOL,
userPoolConfig: {
userPool: userPool,
},
},
},
},
});

Using AWS IAM

import * as appsync from "@aws-cdk/aws-appsync";

new AppSyncApi(this, "GraphqlApi", {
graphqlApi: {
schema: "graphql/schema.graphql",
authorizationConfig: {
defaultAuthorization: {
authorizationType: appsync.AuthorizationType.IAM,
},
},
},
});

Using OpenID Connect

import * as appsync from "@aws-cdk/aws-appsync";

new AppSyncApi(this, "GraphqlApi", {
graphqlApi: {
schema: "graphql/schema.graphql",
authorizationConfig: {
defaultAuthorization: {
authorizationType: appsync.AuthorizationType.OIDC,
openIdConnectConfig: {
oidcProvider: "https://myorg.us.auth0.com",
},
},
},
},
});

Configuring the GraphQL Api

Configure the internally created CDK GraphqlApi instance.

import * as appsync from "@aws-cdk/aws-appsync";

new AppSyncApi(this, "GraphqlApi", {
graphqlApi: {
name: "My GraphQL API",
logConfig: {
excludeVerboseContent: false,
fieldLogLevel: appsync.FieldLogLevel.ALL,
},
xrayEnabled: false,
},
});

Configuring data source

new AppSyncApi(this, "GraphqlApi", {
graphqlApi: {
schema: "graphql/schema.graphql",
},
dataSources: {
notesDS: {
function: {
handler: "src/notes.main",
timeout: 10,
},
options: {
name: "Notes Data Source",
},
},
},
});

Configuring resolver

import { MappingTemplate } from "@aws-cdk/aws-appsync";

new AppSyncApi(this, "GraphqlApi", {
graphqlApi: {
schema: "graphql/schema.graphql",
},
resolvers: {
"Query listNotes": {
function: {
handler: "src/notes.main",
timeout: 10,
},
resolverProps: {
requestMappingTemplate: MappingTemplate.fromFile("request.vtl"),
responseMappingTemplate: MappingTemplate.fromFile("response.vtl"),
},
},
},
});

Importing an existing GraphQL Api

Override the internally created CDK GraphqlApi instance.

import { GraphqlApi } from "@aws-cdk/aws-appsync";

new AppSyncApi(this, "GraphqlApi", {
graphqlApi: GraphqlApi.fromGraphqlApiAttributes(this, "IGraphqlApi", {
graphqlApiId,
}),
resolvers: {
"Query listNotes": "src/list.main",
"Mutation createNote": "src/create.main",
},
});

Attaching permissions

You can attach a set of permissions to all or some of the Lambda functions.

For the entire API

Allow the entire API to access S3.

const api = new AppSyncApi(this, "GraphqlApi", {
graphqlApi: {
schema: "graphql/schema.graphql",
},
resolvers: {
"Query listNotes": "src/list.main",
"Query getNoteById": "src/get.main",
"Mutation createNote": "src/create.main",
"Mutation updateNote": "src/update.main",
"Mutation deleteNote": "src/delete.main",
},
});

api.attachPermissions(["s3"]);

For a specific data source

Allow one of the data sources to access S3.

const api = new AppSyncApi(this, "GraphqlApi", {
graphqlApi: {
schema: "graphql/schema.graphql",
},
dataSources: {
notesDS: "src/notes.main",
billingDS: "src/billing.main",
},
});

api.attachPermissionsToDataSource("billingDS", ["s3"]);

For an auto-created data source

Allow one of the resolvers to access S3.

const api = new AppSyncApi(this, "GraphqlApi", {
graphqlApi: {
schema: "graphql/schema.graphql",
},
resolvers: {
"Query listNotes": "src/list.main",
"Mutation createNote": "src/create.main",
},
});

api.attachPermissionsToDataSource("Query listNotes", ["s3"]);

Getting the data source and resolver

For explicitly configured data source

const api = new AppSyncApi(this, "GraphqlApi", {
graphqlApi: {
schema: "graphql/schema.graphql",
},
dataSources: {
notesDS: "src/notes.main",
billingDS: "src/billing.main",
},
resolvers: {
"Query listNotes": "notesDS",
"Mutation createNote": "notesDS",
"Mutation charge": "billingDS",
},
});

const listFunction = api.getFunction("notesDS");
const dataSource = api.getDataSource("notesDS");
const resolver = api.getResolver("Mutation charge");

For an auto-created data source

const api = new AppSyncApi(this, "GraphqlApi", {
graphqlApi: {
schema: "graphql/schema.graphql",
},
resolvers: {
"Query listNotes": "src/list.main",
"Mutation createNote": "src/create.main",
},
});

const listFunction = api.getFunction("Query listNotes");
const dataSource = api.getDataSource("Query listNotes");
const resolver = api.getResolver("Query listNotes");

Properties

An instance of AppSyncApi contains the following properties.

url

Type: string

The URL of the GraphQL Api.

graphqlApi

Type: cdk.aws-appsync.GraphqlApi

The internally created CDK AppSyncApi instance.

Methods

An instance of Api contains the following methods.

getFunction

getFunction(key: string): Function

Parameters

  • key string

Returns

Get the instance of the internally created Function, for a given data source key. Where the key is the key used to define a data source. For example, lambdaDS.

For auto-created Lambda data sources, pass in the key used to defined a resolver. For example, Query listNotes.

getDataSource

getDataSource(key: string): BaseDataSource

Parameters

  • key string

Returns

Get the instance of the internally created data source. Where the key is the key used to define a data source. For example, lambdaDS.

For auto-created Lambda data sources, pass in the key used to defined a resolver. For example, Query listNotes.

getResolver

getResolver(key: string): Resolver

Parameters

  • key string

Returns

Get the instance of the internally created resolver. Where the key is the key used to defined a resolver. For example, Query listNotes.

addDataSources

addDataSources(scope: cdk.Construct, dataSources: { [key: string]: FunctionDefinition | ApiRouteProps })

Parameters

  • scope cdk.Construct
  • dataSources { [key: string]: FunctionDefinition | AppSyncApiLambdaDataSourceProps | AppSyncApiDynamoDbDataSourceProps | AppSyncApiRdsDataSourceProps | AppSyncApiHttpDataSourceProps }

An associative array with the key being the name as a string and the value is either a FunctionDefinition or one of the AppSyncApiLambdaDataSourceProps, AppSyncApiDynamoDbDataSourceProps, AppSyncApiRdsDataSourceProps, or AppSyncApiHttpDataSourceProps.

addResolvers

addResolvers(scope: cdk.Construct, resolvers: { [key: string]: string | FunctionDefinition | AppSyncApiResolverProps })

Parameters

  • scope cdk.Construct
  • resolvers { [key: string]: string | FunctionDefinition | AppSyncApiResolverProps }

An associative array with the key being the type name and field name as a string and the value is either a string, the FunctionDefinition or the AppSyncApiResolverProps.

attachPermissions

attachPermissions(permissions: Permissions)

Parameters

Attaches the given list of permissions to all the routes. This allows the functions to access other AWS resources.

Internally calls Function.attachPermissions.

attachPermissionsToDataSource

attachPermissionsToDataSource(key: string, permissions: Permissions)

Parameters

Attaches the given list of permissions to a specific data source. This allows that function to access other AWS resources.

Pass in the key used to define a data source. For example, lambdaDS. Or for auto-created Lambda data sources, pass in the key used to defined a resolver. For example, Query listNotes.

Internally calls Function.attachPermissions.

AppSyncApiProps

dataSources?

Type : { [key: string]: FunctionDefinition | AppSyncApiLambdaDataSourceProps | AppSyncApiDynamoDbDataSourceProps | AppSyncApiRdsDataSourceProps | AppSyncApiHttpDataSourceProps }, defaults to {}

The data sources for this API. Takes an associative array, with the key being the name as a string and the value is either a FunctionDefinition.

{
lambdaDataSource: "src/list.main",
}

Or one of the AppSyncApiLambdaDataSourceProps, AppSyncApiDynamoDbDataSourceProps, AppSyncApiRdsDataSourceProps, or AppSyncApiHttpDataSourceProps.

{
lambdaDataSource: {
function: "src/list.main",
options: {
name: "Lambda DS",
},
}
}

resolvers?

Type : { [key: string]: string | FunctionDefinition | AppSyncApiResolverProps }, defaults to {}

The resolvers for this API. Takes an associative array, with the key being the type name and field name as a string and the value is either a string with the name of an existing data source.

{
"Query listNotes": "lambdaDS",
}

A FunctionDefinition. And the data source is automatically created.

{
"Query listNotes": "src/list.main",
}

Or the AppSyncApiResolverProps.

import { MappingTemplate } from "@aws-cdk/aws-appsync";

{
"Query listNotes": {
dataSource: "dynamoDbDataSource",
resolverProps: {
requestMappingTemplate: MappingTemplate.dynamoDbScanTable(),
responseMappingTemplate: MappingTemplate.dynamoDbResultList(),
},
}
}

graphqlApi?

Type : cdk.aws-appsync.IGraphqlApi | AppSyncApiCdkGraphqlProps, defaults to undefined

Optionally, pass in an instance of the CDK cdk.aws-appsync.IGraphqlApi or AppSyncApiCdkGraphqlProps. This will override the default settings this construct uses to create the CDK GraphqlApi internally.

defaultFunctionProps?

Type : FunctionProps, defaults to {}

The default function props to be applied to all the Lambda functions in the API. If the function is specified for a data source, these default values are overridden.

AppSyncApiLambdaDataSourceProps

function

Type : FunctionDefinition

The function definition used to create this data source.

options?

Type : cdk.aws-appsync.DataSourceOptions

The optional configuration for this data source.

AppSyncApiDynamoDbDataSourceProps

table

Type : Table | cdk.aws-dynamodb.Table

The DynamoDB table used to create this data source. Takes a Table or a cdk.aws-dynamodb.Table.

options?

Type : cdk.aws-appsync.DataSourceOptions

The optional configuration for this data source.

AppSyncApiRdsDataSourceProps

serverlessCluster

Type : cdk.aws-rds.IServerlessCluster

The serverless cluster to interact with this data source.

secretStore

Type : cdk.aws-secretsmanager.ISecret

The secret store that contains the username and password for the serverless cluster.

databaseName?

Type : string

The optional name of the database to use within the cluster.

options?

Type : cdk.aws-appsync.DataSourceOptions

The optional configuration for this data source.

AppSyncApiHttpDataSourceProps

endpoint

Type : string

The http endpoint used to create this data source.

options?

Type : cdk.aws-appsync.HttpDataSourceOptions

The optional configuration for this data source.

AppSyncApiResolverProps

dataSource?

Type : string, defaults to undefined

The data source for this resolver. The data source must be already created.

function?

Type : FunctionDefinition

The function definition used to create the data source for this resolver.

resolverProps?

Type : AppSyncApiCdkResolverProps, defaults to undefined

Or optionally pass in a AppSyncApiCdkResolverProps. This allows you to override the default settings this construct uses internally to create the resolver.

AppSyncApiCdkGraphqlProps

AppSyncApiCdkGraphqlProps extends cdk.aws-appsync.GraphqlApiProps with the following exceptions.

name?

Type : string, defaults to the id of the construct

The name field is optional.

schema?

Type : string | string[] | appsync.Schema, defaults to undefined

Pass in the path to the schema attached to this api. Takes either a string.

{
schema: "src/schema.graphql"
}

A list of string. And the schemas are merged using @graphql-tools/merge.

{
schema: [
"src/schema.graphql",
"src/schema2.graphql",
]
}

Or the cdk.aws-appsync.Schema.

import { Schema } from "@aws-cdk/aws-appsync";

{
schema: Schema.fromAsset(schema)
}

xrayEnabled?

Type : boolean, defaults to true

A flag indicating whether or not X-Ray tracing is enabled for this api.

AppSyncApiCdkResolverProps

AppSyncApiCdkResolverProps extends cdk.aws-appsync.BaseResolverProps with the exception that the fieldName and the typeName fields are not accepted. The field name and the type name should be configured using the keys of resolvers field.

You can use AppSyncApiCdkResolverProps to configure the other resolver properties.