Skip to content

Commit cc43dd8

Browse files
author
Jeremiah Langner
committed
feat(dynamodb): add response template support for dynamodb
1 parent acb8ab1 commit cc43dd8

File tree

4 files changed

+108
-24
lines changed

4 files changed

+108
-24
lines changed

README.md

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ This Serverless Framework plugin supports the AWS service proxy integration feat
2626
- [SNS](#sns)
2727
- [Customizing responses](#customizing-responses-2)
2828
- [DynamoDB](#dynamodb)
29+
- [Customizing responses](#customizing-responses-3)
2930
- [EventBridge](#eventbridge)
3031
- [Common API Gateway features](#common-api-gateway-features)
3132
- [Enabling CORS](#enabling-cors)
@@ -446,7 +447,7 @@ custom:
446447
template:
447448
# `success` is used when the integration response is 200
448449
success: |-
449-
{ "message: "accepted" }
450+
{ "message": "accepted" }
450451
# `clientError` is used when the integration response is 400
451452
clientError: |-
452453
{ "message": "there is an error in your request" }
@@ -568,6 +569,40 @@ curl -XPUT https://xxxxxxx.execute-api.us-east-1.amazonaws.com/dev/dynamodb/<has
568569
-H 'Content-Type:application/json'
569570
```
570571

572+
#### Customizing responses
573+
574+
##### Simplified response template customization
575+
576+
You can get a simple customization of the responses by providing a template for the possible responses. The template returns the same kind of response for both `application/json` and `application/x-www-form-urlendcoded`.
577+
578+
```yml
579+
custom:
580+
apiGatewayServiceProxies:
581+
- dynamodb:
582+
path: /dynamodb
583+
method: get
584+
tableName: { Ref: 'YourTable' }
585+
hashKey:
586+
queryStringParam: id # use query string parameter
587+
attributeType: S
588+
rangeKey:
589+
queryStringParam: sort
590+
attributeType: S
591+
action: GetItem
592+
cors: true
593+
response:
594+
template:
595+
# `success` is used when the integration response is 200
596+
success: |-
597+
#set($item = $input.path('$.Item'))
598+
{ "Item": $item }
599+
# `clientError` is used when the integration response is 400
600+
clientError: |-
601+
{ "message": "there is an error in your request" }
602+
# `serverError` is used when the integration response is 500
603+
serverError: |-
604+
{ "message": "there was an error handling your request" }
605+
```
571606
572607
### EventBridge
573608

lib/apiGateway/schema.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,8 @@ const proxiesSchemas = {
300300
condition: Joi.string(),
301301
hashKey: dynamodbDefaultKeyScheme.required(),
302302
rangeKey: dynamodbDefaultKeyScheme,
303-
request
303+
request,
304+
response: extendedResponse
304305
})
305306
}),
306307
eventbridge: Joi.object({

lib/package/dynamodb/compileMethodsToDynamodb.js

Lines changed: 69 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -61,27 +61,64 @@ module.exports = {
6161
RequestTemplates: this.getDynamodbIntegrationRequestTemplates(http)
6262
}
6363

64-
const integrationResponse = {
65-
IntegrationResponses: [
66-
{
67-
StatusCode: 200,
68-
SelectionPattern: '2\\d{2}',
69-
ResponseParameters: {},
70-
ResponseTemplates: this.getDefaultDynamodbResponseTemplates(http)
71-
},
72-
{
73-
StatusCode: 400,
74-
SelectionPattern: '4\\d{2}',
75-
ResponseParameters: {},
76-
ResponseTemplates: {}
77-
},
78-
{
79-
StatusCode: 500,
80-
SelectionPattern: '5\\d{2}',
81-
ResponseParameters: {},
82-
ResponseTemplates: {}
83-
}
84-
]
64+
let integrationResponse
65+
66+
if (_.get(http.response, 'template.success')) {
67+
// support a simplified model
68+
integrationResponse = {
69+
IntegrationResponses: [
70+
{
71+
StatusCode: 200,
72+
SelectionPattern: 200,
73+
ResponseParameters: {},
74+
ResponseTemplates: this.getSnsIntegrationResponseTemplate(http, 'success')
75+
},
76+
{
77+
StatusCode: 400,
78+
SelectionPattern: 400,
79+
ResponseParameters: {},
80+
ResponseTemplates: this.getSnsIntegrationResponseTemplate(http, 'clientError')
81+
},
82+
{
83+
StatusCode: 500,
84+
SelectionPattern: 500,
85+
ResponseParameters: {},
86+
ResponseTemplates: this.getSnsIntegrationResponseTemplate(http, 'serverError')
87+
}
88+
]
89+
}
90+
} else if (_.isArray(http.response)) {
91+
integrationResponse = {
92+
IntegrationResponses: http.response.map((i) => ({
93+
StatusCode: i.statusCode,
94+
SelectionPattern: i.selectionPattern || i.statusCode,
95+
ResponseParameters: i.responseParameters || {},
96+
ResponseTemplates: i.responseTemplates || {}
97+
}))
98+
}
99+
} else {
100+
integrationResponse = {
101+
IntegrationResponses: [
102+
{
103+
StatusCode: 200,
104+
SelectionPattern: '2\\d{2}',
105+
ResponseParameters: {},
106+
ResponseTemplates: this.getDefaultDynamodbResponseTemplates(http, 'success')
107+
},
108+
{
109+
StatusCode: 400,
110+
SelectionPattern: '4\\d{2}',
111+
ResponseParameters: {},
112+
ResponseTemplates: {}
113+
},
114+
{
115+
StatusCode: 500,
116+
SelectionPattern: '5\\d{2}',
117+
ResponseParameters: {},
118+
ResponseTemplates: {}
119+
}
120+
]
121+
}
85122
}
86123

87124
this.addCors(http, integrationResponse)
@@ -143,6 +180,17 @@ module.exports = {
143180
}
144181
},
145182

183+
getDynamodbResponseTemplates(http, statusType) {
184+
const template = _.get(http, ['response', 'template', statusType])
185+
return Object.assign(
186+
{},
187+
template && {
188+
'application/json': template,
189+
'application/x-www-form-urlendcoded': template
190+
}
191+
)
192+
},
193+
146194
getDefaultDynamodbResponseTemplates(http) {
147195
if (http.action === 'GetItem') {
148196
return {

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "serverless-apigateway-service-proxy",
33
"version": "2.0.0",
4-
"description": "The Serverless Framewrok plugin for supporting AWS service proxy integration of API Gateway",
4+
"description": "The Serverless Framework plugin for supporting AWS service proxy integration of API Gateway",
55
"main": "lib/index.js",
66
"scripts": {
77
"lint": "eslint .",

0 commit comments

Comments
 (0)