Skip to content

Commit 366a841

Browse files
authored
Merge pull request #131 from vlewin/master
Closes #130 Shared API Gateway and maxAge property support for HTTP Endpoints
2 parents eeb0cb0 + 36bb3a4 commit 366a841

File tree

15 files changed

+1847
-431
lines changed

15 files changed

+1847
-431
lines changed

CHANGELOG.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# 0.2.0(08.01.2017)
22
## Breaking Changes
3-
The service name is added to the statemachin prefix.
3+
The service name is added to the statemachine prefix.
44
This is because there is a possibility of conflict with the state machine deployed from another service without the service name.
55

66
A state machine created with version 0.1 is not inherited. Please recreate it.
@@ -18,4 +18,4 @@ A state machine created with version 0.1 is not inherited. Please recreate it.
1818
Accidentally release(#1)
1919

2020
# 0.1.1(29.12.2016)
21-
First Release
21+
First Release

README.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,53 @@ stepFunctions:
169169
definition:
170170
```
171171

172+
#### Share API Gateway and API Resources
173+
174+
You can [share the same API Gateway](https://serverless.com/framework/docs/providers/aws/events/apigateway/#share-api-gateway-and-api-resources) between multiple projects by referencing its REST API ID and Root Resource ID in serverless.yml as follows:
175+
176+
```yml
177+
service: service-name
178+
provider:
179+
name: aws
180+
apiGateway:
181+
# REST API resource ID. Default is generated by the framework
182+
restApiId: xxxxxxxxxx
183+
# Root resource, represent as / path
184+
restApiRootResourceId: xxxxxxxxxx
185+
186+
functions:
187+
...
188+
```
189+
If your application has many nested paths, you might also want to break them out into smaller services.
190+
191+
However, Cloudformation will throw an error if we try to generate an existing path resource. To avoid that, we reference the resource ID:
192+
193+
```yml
194+
service: service-a
195+
provider:
196+
apiGateway:
197+
restApiId: xxxxxxxxxx
198+
restApiRootResourceId: xxxxxxxxxx
199+
# List of existing resources that were created in the REST API. This is required or the stack will be conflicted
200+
restApiResources:
201+
/users: xxxxxxxxxx
202+
203+
functions:
204+
...
205+
```
206+
207+
Now we can define endpoints using existing API Gateway ressources
208+
209+
```yml
210+
stepFunctions:
211+
stateMachines:
212+
hello:
213+
events:
214+
- http:
215+
path: users/create
216+
method: POST
217+
```
218+
172219
#### Enabling CORS
173220

174221
To set CORS configurations for your HTTP endpoints, simply modify your event configurations as follows:
@@ -210,6 +257,21 @@ stepFunctions:
210257

211258
Configuring the cors property sets Access-Control-Allow-Origin, Access-Control-Allow-Headers, Access-Control-Allow-Methods,Access-Control-Allow-Credentials headers in the CORS preflight response.
212259

260+
To enable the Access-Control-Max-Age preflight response header, set the maxAge property in the cors object:
261+
262+
```yml
263+
stepFunctions:
264+
stateMachines:
265+
SfnApiGateway:
266+
events:
267+
- http:
268+
path: /playground/start
269+
method: post
270+
cors:
271+
origin: '*'
272+
maxAge: 86400
273+
```
274+
213275
#### Customizing request body mapping templates
214276

215277
The plugin generates default body mapping templates for `application/json` and `application/x-www-form-urlencoded` content types. If you'd like to add more content types or customize the default ones, you can do so by including them in `serverless.yml`:

lib/deploy/events/apiGateway/cors.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ module.exports = {
1212
const corsMethodLogicalId = this.provider.naming
1313
.getMethodLogicalId(resourceName, 'options');
1414

15+
// TODO remove once "origins" config is deprecated
1516
let origin = config.origin;
1617
if (config.origins && config.origins.length) {
1718
origin = config.origins.join(',');
@@ -24,6 +25,16 @@ module.exports = {
2425
'Access-Control-Allow-Credentials': `'${config.allowCredentials}'`,
2526
};
2627

28+
// Enable CORS Max Age usage if set
29+
if (_.has(config, 'maxAge')) {
30+
if (_.isInteger(config.maxAge) && config.maxAge > 0) {
31+
preflightHeaders['Access-Control-Max-Age'] = `'${config.maxAge}'`;
32+
} else {
33+
const errorMessage = 'maxAge should be an integer over 0';
34+
throw new this.serverless.classes.Error(errorMessage);
35+
}
36+
}
37+
2738
if (_.includes(config.methods, 'ANY')) {
2839
preflightHeaders['Access-Control-Allow-Methods'] =
2940
preflightHeaders['Access-Control-Allow-Methods']
@@ -43,10 +54,11 @@ module.exports = {
4354
RequestTemplates: {
4455
'application/json': '{statusCode:200}',
4556
},
57+
ContentHandling: 'CONVERT_TO_TEXT',
4658
IntegrationResponses: this.generateCorsIntegrationResponses(preflightHeaders),
4759
},
4860
ResourceId: resourceRef,
49-
RestApiId: { Ref: this.apiGatewayRestApiLogicalId },
61+
RestApiId: this.provider.getApiGatewayRestApiId(),
5062
},
5163
},
5264
});

0 commit comments

Comments
 (0)