integration/resources/templates/combination/connector_appsync_to_table.yaml (183 lines of code) (raw):
Resources:
NotesTable:
Type: AWS::Serverless::SimpleTable
Properties:
PrimaryKey:
Name: NoteId
Type: String
DynamoDBRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- sts:AssumeRole
Principal:
Service:
- appsync.amazonaws.com
AppSyncApi:
Type: AWS::AppSync::GraphQLApi
Properties:
AuthenticationType: API_KEY
Name: AppSyncApi
ApiKey:
Type: AWS::AppSync::ApiKey
Properties:
ApiId: !GetAtt AppSyncApi.ApiId
ApiSchema:
Type: AWS::AppSync::GraphQLSchema
Properties:
ApiId: !GetAtt AppSyncApi.ApiId
Definition: |
type Note {
NoteId: ID!
title: String
content: String
}
type Query {
getNote(NoteId: ID!): Note
}
type Mutation {
saveNote(NoteId: ID!, title: String!, content: String!): Note!
}
schema {
query: Query
mutation: Mutation
}
NotesTableDataSource:
Type: AWS::AppSync::DataSource
Properties:
ApiId: !GetAtt AppSyncApi.ApiId
Name: NotesTableDataSource
Type: AMAZON_DYNAMODB
ServiceRoleArn: !GetAtt DynamoDBRole.Arn
DynamoDBConfig:
TableName: !Ref NotesTable
AwsRegion: !Sub ${AWS::Region}
GetNoteResolver:
Type: AWS::AppSync::Resolver
DependsOn: ApiSchema
Properties:
ApiId: !GetAtt AppSyncApi.ApiId
DataSourceName: !GetAtt NotesTableDataSource.Name
TypeName: Query
FieldName: getNote
RequestMappingTemplate: |
{
"version": "2017-02-28",
"operation": "GetItem",
"key": {
"NoteId": $util.dynamodb.toDynamoDBJson($context.arguments.NoteId)
}
}
ResponseMappingTemplate: $util.toJson($context.result)
SaveNoteResolver:
Type: AWS::AppSync::Resolver
DependsOn: ApiSchema
Properties:
ApiId: !GetAtt AppSyncApi.ApiId
TypeName: Mutation
FieldName: saveNote
DataSourceName: !GetAtt NotesTableDataSource.Name
RequestMappingTemplate: |
{
"version": "2017-02-28",
"operation": "PutItem",
"key": {
"NoteId": $util.dynamodb.toDynamoDBJson($context.arguments.NoteId)
},
"attributeValues": {
"title": $util.dynamodb.toDynamoDBJson($context.arguments.title),
"content": $util.dynamodb.toDynamoDBJson($context.arguments.content)
}
}
ResponseMappingTemplate: $util.toJson($context.result)
DataSourceToTableConnector:
Type: AWS::Serverless::Connector
Properties:
Source:
Id: NotesTableDataSource
Destination:
Id: NotesTable
Permissions:
- Read
- Write
TriggerFunction:
Type: AWS::Serverless::Function
Properties:
Environment:
Variables:
API_KEY: !GetAtt ApiKey.ApiKey
GRAPHQL_URL: !GetAtt AppSyncApi.GraphQLUrl
Runtime: nodejs18.x
Handler: index.handler
InlineCode: |
const https = require("https");
exports.handler = async (_) => {
const queries = {
getNote: /* GraphQL */ `
query {
getNote(NoteId: "1") {
title
content
}
}
`,
saveNote: /* GraphQL */ `
mutation {
saveNote(content: "some note", NoteId: "1", title: "1st note") {
title
content
}
}
`,
};
const fetch = async (url, options) =>
new Promise((resolve, reject) => {
const req = https.request(url, options, (res) => {
const body = [];
res.on("data", (chunk) => body.push(chunk));
res.on("end", () => {
const resString = Buffer.concat(body).toString();
resolve(resString);
});
});
req.on("error", (err) => {
reject(err);
});
req.on("timeout", () => {
req.destroy();
reject(new Error("Request time out"));
});
req.write(options.body);
req.end();
});
const makeRequest = async (queryName) => {
const options = {
method: "POST",
headers: {
"x-api-key": process.env.API_KEY,
},
body: JSON.stringify({ query: queries[queryName] }),
timeout: 10000, // ms
};
const response = await fetch(process.env.GRAPHQL_URL, options);
let body = JSON.parse(response);
const data = body.data?.[queryName];
if (body.errors !== undefined) {
throw JSON.stringify(body.errors);
}
if (data?.title !== "1st note" || data?.content !== "some note") {
throw new Error(
`${queryName} error: '${data?.title}' must be '1st note', '${data?.content}' must be 'some note'`);
}
return body.data;
};
const saveResponse = await makeRequest("saveNote");
const getResponse = await makeRequest("getNote");
return { ...saveResponse, ...getResponse };
};
Metadata:
SamTransformTest: true