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",
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",
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.