作りたいもの
CDKでつくるMutation, Query, Subscriptionをするだけのできるだけ小さいサンプル
完成品 https://github.com/tky/app-sync-example
注意点
Subscripiton使うためにはschemaをcodeで定義する必要があります。
ネットによくあるappsync.Schema.fromAsset
を使ってschemaを定美すると、
Unable to add subscription. Schema definition mode must be ...とかいっておこられてしまいます。
aws-cdk/aws-appsync-alpha使っているので将来breaking changesがある可能性があります。
実装
importないsampleで苦しむことが多いので一応。。
import * as cdk from "aws-cdk-lib";
import { Construct } from "constructs";
import { Table, AttributeType } from "aws-cdk-lib/aws-dynamodb";
import {
AuthorizationType,
Directive,
GraphqlApi,
Field,
GraphqlType,
InputType,
MappingTemplate,
ObjectType,
PrimaryKey,
Values,
ResolvableField,
Schema,
} from "@aws-cdk/aws-appsync-alpha";
import { RemovalPolicy } from "aws-cdk-lib";
nameとageだけ持つuserを定義してみます。
MutationするためにInputTypeも。
const typeUser = new ObjectType("User", {
definition: {
id: GraphqlType.string({ isRequired: true }),
name: GraphqlType.string({ isRequired: true }),
age: GraphqlType.int({ isRequired: false }),
},
});
const typeUserInput = new InputType("UserInput", {
definition: {
name: GraphqlType.string({ isRequired: true }),
age: GraphqlType.int({ isRequired: false }),
},
});
const schema = new Schema();
schema.addType(typeUser);
schema.addType(typeUserInput);
const api = new GraphqlApi(this, "api", {
name: "app-sync-example-api",
schema,
authorizationConfig: {
defaultAuthorization: {
authorizationType: AuthorizationType.API_KEY,
},
},
xrayEnabled: false,
});
const table = new Table(this, "table", {
tableName: "app-sync-example-table",
partitionKey: {
name: "id",
type: AttributeType.STRING,
},
removalPolicy: RemovalPolicy.DESTROY,
});
DataSourceはDynamoDB
const dataSource = api.addDynamoDbDataSource("data_source", table);
Query
schema.addQuery(
"getUser",
new ResolvableField({
returnType: typeUser.attribute(),
args: {
id: GraphqlType.id({ isRequired: true }),
},
dataSource,
requestMappingTemplate: MappingTemplate.dynamoDbGetItem("id", "id"),
responseMappingTemplate: MappingTemplate.dynamoDbResultItem(),
})
);
Mutation
idはautoではなく指定するようにしています。
schema.addMutation(
"addUser",
new ResolvableField({
returnType: typeUser.attribute(),
args: {
id: GraphqlType.string({ isRequired: true }),
input: typeUserInput.attribute({ isRequired: true }),
},
dataSource,
requestMappingTemplate: MappingTemplate.dynamoDbPutItem(
PrimaryKey.partition("id").is("id"),
Values.projecting("input")
),
responseMappingTemplate: MappingTemplate.dynamoDbResultItem(),
})
);
idは指定するからってInputTypeにいれるとだめでした。
// 動かないサンプル
const typeUserInput = new InputType("UserInput", {
definition: {
// idをInputのdefinitionにいれるとだめ
id: GraphqlType.string({ isRequired: true }),
name: GraphqlType.string({ isRequired: true }),
age: GraphqlType.int({ isRequired: false }),
},
});
schema.addMutation(
"addUser",
...
requestMappingTemplate: MappingTemplate.dynamoDbPutItem(
Values.projecting("input")
)
})
);
Subscription
schema.addSubscription(
"updatedUser",
new Field({
returnType: typeUser.attribute(),
args: { id: GraphqlType.id({ isRequired: true }) },
directives: [Directive.subscribe("addUser")],
})
);
awsのconsoleログインしてAWS AppSyncから作ったAPIを選択、Queriesで試せます。
コマンドでするための方法も用意したのでお好みでどうぞ