Skip to content

Commit 57ef4e1

Browse files
author
Dane Pilcher
authored
add batch ddb operations page (#8145)
1 parent e5ec8b9 commit 57ef4e1

File tree

2 files changed

+156
-0
lines changed
  • src
    • directory
    • pages/[platform]/build-a-backend/data/custom-business-logic/batch-ddb-operations

2 files changed

+156
-0
lines changed

src/directory/directory.mjs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,9 @@ export const directory = {
292292
},
293293
{
294294
path: 'src/pages/[platform]/build-a-backend/data/custom-business-logic/connect-http-datasource/index.mdx'
295+
},
296+
{
297+
path: 'src/pages/[platform]/build-a-backend/data/custom-business-logic/batch-ddb-operations/index.mdx'
295298
}
296299
]
297300
},
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
import { getCustomStaticPath } from '@/utils/getCustomStaticPath';
2+
3+
export const meta = {
4+
title: 'Batch DynamoDB Operations',
5+
description:
6+
'Batch DynamoDB Operations',
7+
platforms: [
8+
'android',
9+
'angular',
10+
'flutter',
11+
'javascript',
12+
'nextjs',
13+
'react',
14+
'react-native',
15+
'swift',
16+
'vue'
17+
]
18+
};
19+
20+
export const getStaticPaths = async () => {
21+
return getCustomStaticPath(meta.platforms);
22+
};
23+
24+
export function getStaticProps() {
25+
return {
26+
props: {
27+
meta
28+
}
29+
};
30+
}
31+
32+
Batch DynamoDB operations allow you to add multiple items in single mutation.
33+
34+
## Step 1 - Define a custom mutation
35+
36+
```ts title="amplify/data/resource.ts"
37+
import { type ClientSchema, a, defineData } from '@aws-amplify/backend';
38+
39+
const schema = a.schema({
40+
// 1. Define your return type as a custom type or model
41+
Post: a.model({
42+
id: a.id(),
43+
content: a.string(),
44+
likes: a.integer()
45+
}),
46+
47+
// 2. Define your mutation with the return type and, optionally, arguments
48+
BatchCreatePost: a
49+
.mutation()
50+
// arguments that this query accepts
51+
.arguments({
52+
content: a.string().array()
53+
})
54+
.returns(a.ref('Post').array())
55+
// only allow signed-in users to call this API
56+
.authorization(allow => [allow.authenticated()])
57+
});
58+
59+
export type Schema = ClientSchema<typeof schema>;
60+
61+
export const data = defineData({
62+
schema
63+
});
64+
```
65+
66+
## Step 2 - Configure custom business logic handler code
67+
68+
After your query or mutation is defined, you need to author your custom business logic using a [custom resolver powered by AppSync JavaScript resolver](https://docs.aws.amazon.com/appsync/latest/devguide/tutorials-js.html).
69+
70+
Custom resolvers work on a "request/response" basis. You choose a data source, map your request to the data source's input parameters, and then map the data source's response back to the query/mutation's return type. Custom resolvers provide the benefit of no cold starts, less infrastructure to manage, and no additional charge for Lambda function invocations. Review [Choosing between custom resolver and function](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-reference-overview-js.html#choosing-data-source).
71+
72+
In your `amplify/data/resource.ts` file, define a custom handler using `a.handler.custom`.
73+
74+
```ts title="amplify/data/resource.ts"
75+
import { type ClientSchema, a, defineData } from '@aws-amplify/backend';
76+
77+
const schema = a.schema({
78+
Post: a.model({
79+
id: a.id(),
80+
content: a.string(),
81+
likes: a.integer()
82+
}),
83+
84+
BatchCreatePost: a
85+
.mutation()
86+
.arguments({
87+
contents: a.string().array()
88+
})
89+
.returns(a.ref('Post').array())
90+
.authorization(allow => [allow.authenticated()])
91+
// 1. Add the custom handler
92+
.handler(
93+
a.handler.custom({
94+
dataSource: a.ref('Post'),
95+
entry: './BatchCreatePostHandler.js',
96+
})
97+
)
98+
});
99+
100+
export type Schema = ClientSchema<typeof schema>;
101+
102+
export const data = defineData({
103+
schema
104+
});
105+
```
106+
107+
Amplify will store some values in the resolver context stash that can be accessed in the custom resolver.
108+
109+
| Name | Description |
110+
| ------------------------- | -------------------------------------------- |
111+
| awsAppsyncApiId | The ID of the AppSync API. |
112+
| amplifyApiEnvironmentName | The Amplify api environment name. (`NONE` in sandbox) |
113+
114+
The Amplify generated DynamoDB table names can be constructed from the variables in the context stash. The table name is in the format `<model-name>-<aws-appsync-api-id>-<amplify-api-environment-name>`. For example, the table name for the `Post` model would be `Post-123456-dev` where `123456` is the AppSync API ID and `dev` is the Amplify API environment name.
115+
116+
```ts title="amplify/data/BatchCreatePostHandler.js"
117+
import { util } from '@aws-appsync/utils';
118+
119+
export function request(ctx) {
120+
var now = util.time.nowISO8601();
121+
122+
return {
123+
operation: 'BatchPutItem',
124+
tables: {
125+
[`Post-${ctx.stash.awsAppsyncApiId}-${ctx.stash.amplifyApiEnvironmentName}`]: ctx.args.contents.map((content) =>
126+
util.dynamodb.toMapValues({
127+
content,
128+
id: util.autoId(),
129+
createdAt: now,
130+
updatedAt: now,
131+
})
132+
),
133+
},
134+
};
135+
}
136+
137+
export function response(ctx) {
138+
if (ctx.error) {
139+
util.error(ctx.error.message, ctx.error.type);
140+
}
141+
return ctx.result.data[`Post-${ctx.stash.awsAppsyncApiId}-${ctx.stash.amplifyApiEnvironmentName}`];
142+
}
143+
```
144+
145+
## Step 3 - Invoke the custom query or mutation
146+
147+
From your generated Data client, you can find all your custom queries and mutations under the `client.queries.` and `client.mutations.` APIs respectively.
148+
149+
```ts
150+
const { data, errors } = await client.mutations.BatchCreatePost({
151+
contents: ['Post 1', 'Post 2', 'Post 3']
152+
});
153+
```

0 commit comments

Comments
 (0)