UNPKG

19 kBMarkdownView Raw
1<p align="center">
2 <a href="https://npmjs.com/package/serverless-openapi-integration-helper">
3 <img src="https://flat.badgen.net/npm/v/serverless-openapi-integration-helper?icon=npm&label=npm@latest"></a>
4<a href="https://www.npmjs.com/package/serverless-openapi-integration-helper">
5 <img src="https://flat.badgen.net/npm/dt/serverless-openapi-integration-helper?icon=npm"></a>
6 <a href="https://packagephobia.now.sh/result?p=serverless-openapi-integration-helper">
7 <img src="https://flat.badgen.net/packagephobia/install/serverless-openapi-integration-helper"></a>
8 <a href="https://www.npmjs.com/package/serverless-openapi-integration-helper">
9 <img src="https://flat.badgen.net/npm/license/serverless-openapi-integration-helper"></a>
10 <br/>
11</p>
12
13_Feedback is appreciated! If you have an idea for how this plugin/library can be improved (or even just a complaint/criticism) then please open an issue._
14
15# Serverless Plugin: AWS Api Gateway integration helper
16
171. [Overview](#overview)
181. [Installation & Setup](#installation--setup)
191. [Plugin configuration](#plugin-configuration)
201. [Usage](#usage)
211. [Command](#commands)
221. [CORS Generator](#cors-generator)
231. [AUTO-MOCK Generator](#auto-mock-generator)
241. [VALIDATION Generator](#validation-generator)
251. [PROXY Manager](#proxy-manager)
261. [Configuration Reference](#configuration-reference)
271. [Known Issues](#known-issues)
28 1. [Stage Deployment](#stage-deployment)
29 1. [Variable Resolving](#variable-resolving)
301. [Example](#example)
311. [Approach to a functional test of schema validation](#approach-to-a-functional-test-of-schema-validation)
32
33# Overview
34The plugin provides the functionality to merge [OpenApiSpecification files](https://swagger.io/specification/) (formerly known as swagger) with one or multiple YML files containing the the x-amazon-apigateway extensions.
35There are several use-cases to keep both information separated, e.g. it is needed to deploy different api gateway integrations depending on a stage environment.
36
37When dealing with functional tests you do not want to test the production environment, but only a mocking response.
38
39**The plugin supports YML based OpenApi3 specification files only**
40
41## Features
42- Serverless 3.x Support
43- deploy stage dependent x-amazon-apigateway integrations
44- separate infrastructure (aws) from openapi specification
45- use mock integrations for functional testing
46- auto-generating CORS methods, headers and api gateway mocking response
47- hook into package & deploy lifeCycle and generate combined openApi files on the fly during deployment
48- auto-inject generated openApi file into the Body property of specified API Gateway
49- generate mocking responses without specifying x-amazon-apigateway-integration objects
50- generate request-validation blocks
51- generate all required x-amazon-apigateway-integration objects automatically
52- full proxy generation support with **[NEW]:** feature: [PROXY Manager](#proxy-manager)
53
54See the **examples** folder for a full working [example](https://github.com/yndlingsfar/serverless-openapi-integration-helper/tree/main/examples)
55
56# Installation & Setup
57
58Run `npm install` in your Serverless project.
59
60`$ npm install --save-dev serverless-openapi-integration-helper`
61
62Add the plugin to your serverless.yml file
63
64```yml
65plugins:
66 - serverless-openapi-integration-helper
67```
68# Plugin configuration
69You can configure the plugin under the key **openApiIntegration**. See
70See [Configuration Reference](#configuration-reference) for a list of available options
71
72The value for `openApiIntegration` must be either a single object or an array of objects.
73For an array of objects, the `apiResourceName` property must be specified in each object to determine
74which `Aws::ApiGateway::RestApi` resource to insert the merged API specification into,
75while for a single object it's optional and will default to the first found
76`Aws::ApiGateway::RestApi` resource.
77
78The mapping array must be used to configure where the files containing the **x-amazon-apigateway-integration** blocks are located.
79
80```yml
81openApiIntegration:
82 package: true #New feature! Hook into the package & deploy process
83 inputFile: schema.yml
84 mapping:
85 - stage: [dev, prod] #multiple stages
86 path: integrations
87 - stage: test #single stage
88 path: mocks
89```
90
91In the above example all YML files inside the _integrations_ directory will be processed and merged with the schema.yml file when deploying the dev stage
92```shell
93serverless deploy --stage=dev
94```
95
96To use a different x-amazon-apigateway to perform functional tests (with mocking responses e.g) the directory mock is processed and merged with the schema.yml file when deploying the test stage
97```shell
98serverless deploy --stage=test
99```
100
101## Multiple APIs
102
103To handle multiple APIs, supply an array as the value of `openApiIntegrations`
104instead of a single object, and specify the target `Aws::ApiGateway::RestApi`
105resource for each item using the `apiResourceName` property, and make sure to specify
106unique output files by setting `outputDirectory` and/or `outputFile` uniquely:
107
108```yml
109openApiIntegration:
110 - package: true
111 inputFile: schema-1.yml
112 apiResourceName: Api1
113 outputFile: api-1.yml
114 mapping:
115 - stage: [dev, prod]
116 path: integrations/api-1
117 - package: true
118 inputFile: schema-2.yml
119 apiResourceName: Api2
120 outputFile: api-2.yml
121 mapping:
122 - stage: [dev, prod]
123 path: integrations/api-2
124
125...
126
127resources:
128 Resources:
129 Api1:
130 Type: AWS::ApiGateway::RestApi
131 Properties:
132 Body: ~ # auto-generated by plugin from schema-1
133
134 ...
135
136 Api2:
137 Type: AWS::ApiGateway::RestApi
138 Properties:
139 Body: ~ # auto-generated by plugin from schema-2
140
141 ...
142```
143
144# Usage
145You can setup a fully working API GATEWAY with any openApi 3.0 specification file
146First create the input file containing the [OpenApiSpecification](https://swagger.io/specification/)
147```yml
148# ./schema.yml
149openapi: 3.0.0
150info:
151 description: User Registration
152 version: 1.0.0
153 title: UserRegistration
154paths:
155 /api/v1/user:
156 post:
157 summary: adds a user
158 requestBody:
159 content:
160 application/json:
161 schema:
162 $ref: '#/components/schemas/Customer'
163 responses:
164 '201':
165 description: user created
166components:
167 schemas:
168 Customer:
169 type: object
170 required:
171 - email_address
172 - password
173 properties:
174 email_address:
175 type: string
176 example: test@example.com
177 password:
178 type: string
179 format: password
180 example: someStrongPassword#
181```
182
183The plugin will generate the **x-amazon-apigateway integrations** objects for all methods that do not have an integration.
184
185```yml
186#generate a file containing a gateway mock integration in the directory /mocks
187serverless integration create --output mocks --type mock --stage=test
188
189#generate a file containing the production integration in the directory integrations/
190serverless integration create --output integrations --type http --stage=prod
191```
192
193Supported types are
194- http_proxy
195- http
196- aws
197- aws_proxy
198- mock
199
200
201The plugin now generates a merged file during deployment that is automatically injected in your serverless resources
202
203```shell
204#Create OpenApi File containing mocking responses (usable in functional tests) and deploy to ApiGateway
205serverless deploy --stage==test
206```
207
208```shell
209#Create OpenApi File containing the production integration and deploy to ApiGateway
210serverless deploy --stage=prod
211```
212
213The generated output is automatically injected in the **resources.Resources.YOUR_API_GATEWAY.Properties.Body** property
214```yml
215resources:
216 Resources:
217 ApiGatewayRestApi:
218 Type: AWS::ApiGateway::RestApi
219 Properties:
220 ApiKeySourceType: HEADER
221 Body: ~ #autogenerated by plugin
222 Description: "Some Description"
223 FailOnWarnings: false
224 Name: ${opt:stage, self:provider.stage}-some-name
225 EndpointConfiguration:
226 Types:
227 - REGIONAL
228 ApiGatewayDeployment:
229 Type: AWS::ApiGateway::Deployment
230 Properties:
231 RestApiId:
232 Ref: ApiGatewayRestApi
233 StageName: ${opt:stage, self:provider.stage}
234```
235
236# Commands
237
238## Manual merge
239The generate command can be used independently with
240```yml
241serverless integration merge --stage=dev
242```
243Of course then the API Gateway Body property has to be specified manually
244
245```yml
246resources:
247 Resources:
248 ApiGatewayRestApi:
249 Type: AWS::ApiGateway::RestApi
250 Properties:
251 ApiKeySourceType: HEADER
252 Body: ${file(openapi-integration/api.yml)}
253```
254
255# CORS generator
256
257The plugin can generate full CORS support out of the box.
258```yml
259openApiIntegration:
260 cors: true
261 ...
262```
263
264If enabled, the plugin generates all required OPTIONS methods as well as the required header informations and adds a mocking response to API Gateway.
265You can customize the CORS templates by placing your own files inside a directory **openapi-integration** (in your project root). The following files can be overwritten:
266
267| Filename | Description |
268| ------------- |:-------------:|
269| headers.yml | All headers required for CORS support |
270| integration.yml | Contains the x-amazon-apigateway-integration block |
271| path.yml| OpenApi specification for the OPTIONS method |
272| response-parameters.yml| The response Parameters of the x-amazon-apigateway-integration responses |
273
274See the [EXAMPLES](https://github.com/yndlingsfar/serverless-openapi-integration-helper/tree/main/examples) directory for detailed instructions.
275
276# Auto Mock Generator
277If enabled, the plugin generates mocking responses for all methods that do not have an x-amazon-apigateway-integration block defined.
278It takes the first 2xx response defined in the openApi specification and generates a simple mocking response on the fly
279```yml
280openApiIntegration:
281 autoMock: true
282 ...
283```
284
285When using the autoMock feature, you do not need to specify inputPath mappings, since all endpoints are mocked automatically
286
287```yml
288openApiIntegration:
289 package: true
290 inputFile: schema.yml
291 mapping: ~
292```
293
294# VALIDATION generator
295
296The plugin supports full request validation out of the box
297```yml
298openApiIntegration:
299 validation: true
300 ...
301```
302
303If enabled, the plugin generates the x-amazon-apigateway-request-validators blocks and adds a basic request validation to all methods.
304You can customize the VALIDATION template by placing your own files inside a directory **openapi-integration** (in your project root). The following files can be overwritten:
305
306| Filename | Description |
307| ------------- |:-------------:|
308| request-validator.yml | The x-amazon-apigateway-request-validators block |
309
310See the [EXAMPLES](https://github.com/yndlingsfar/serverless-openapi-integration-helper/tree/main/examples) directory for detailed instructions.
311
312# Proxy Manager
313
314The proxymanager feature automates the complete generation of an HTTP proxy integration.
315You only have to define the target URL and all necessary AWS integration blocks are generated on-the-fly during deployment.
316
317
318```yml
319openApiIntegration:
320 cors: true
321 validation: true
322 mapping:
323 - stage: [dev, prod]
324 proxyManager:
325 type: http_proxy
326 baseUrl: https://www.example.com
327 pattern: "(?<=api\/v1)\/.+"
328 ...
329```
330
331**With this setting, no separate integration files need to be created**
332
333A combination of your own and auto-generated files is still possible without any problems
334
335## Proxy Manager configuration
336### type
337at the moment only http_proxy supported
338
339### baseUrl
340The base url is required to map the path variable from the openapi specification to the URI from the aws integration.
341
342Example:
343
344```yml
345#original openapi specification
346paths:
347 /api/v1/user:
348 post:
349 ...
350```
351
352will be translated to
353
354```yml
355#generated openapi specification output
356paths:
357 /api/v1/user:
358 post:
359 ...
360 x-amazon-apigateway-integration:
361 type: http_proxy
362 passthroughBehavior: when_no_match
363 httpMethod: POST
364 uri: https://www.example.com/api/v1/user
365```
366
367### pattern
368
369The pattern can be used to adapt the mapping of the base url using regexp, to remove a prefix, or a version string
370
371Example:
372
373```yml
374baseUrl: https://www.example.com
375pattern: "(?<=api\/v1)\/.+"
376```
377
378will translate the route **/api/v1/user** to https://www.example.com/user
379
380# Configuration Reference
381
382configure the plugin under the key **openApiIntegration**
383
384```yml
385openApiIntegration:
386 inputFile: schema.yml #required
387 package: true #optional, defaults to false
388 inputDirectory: ./ #optional, defaults to ./
389 cors: true #optional, defaults to false
390 autoMock: true #optional, defaults to false
391 validation: true #optional, defaults to false
392 mapping: #optional, can be completely blank if autoMock option is enabled
393 - stage: [dev, prod] #multiple stages
394 path: integrations
395 proxyManager: #optional
396 type: http_proxy
397 baseUrl: https://example.com
398 pattern: "(?<=v1)\/.+"
399 - stage: test #single stage
400 path: mocks/customer.yml
401 outputFile: api.yml #optional, defaults to api.yml
402 outputDirectory: openapi-integration #optional, defaults to ./openapi-integration
403```
404
405# Known Issues
406
407## Stage deployment
408When using serverless framework only to deploy your aws resources **without having any lambda functions or triggers**, the AWS Gateway deploymemt does not behave as expected.
409Any deployment to an existing stage will be ignored, since CloudFormation does not redeploy a stage if the DeploymentIdentifier has not changed.
410
411The plugin [serverless-random-gateway-deployment-id](https://www.npmjs.com/package/serverless-random-gateway-deployment-id) solves this problem by adding a random id to the deployment-name and all references to it on every deploy
412
413See the **examples** folder for a full working [example](https://github.com/yndlingsfar/serverless-openapi-integration-helper/tree/main/examples)
414
415## Variable Resolving
416Serverless variables inside the openapi integration files are not resolved correctly when using the package & deploy hooks. This problem can be solved by using the api gateway STAGE VARIABLES.
417
418See the **examples** folder for a full working [example](https://github.com/yndlingsfar/serverless-openapi-integration-helper/tree/main/examples)
419
420# Example
421```yml
422service:
423 name: user-registration
424
425provider:
426 name: aws
427 stage: dev
428 region: eu-central-1
429
430plugins:
431 - serverless-openapi-integration-helper
432
433openApiIntegration:
434 inputFile: schema.yml
435 package: true
436 mapping:
437 - path: integrations
438 stage: [dev, prod]
439 - path: mocks/customer.yml
440 stage: test
441
442functions:
443
444resources:
445 Resources:
446 ApiGatewayRestApi:
447 Type: AWS::ApiGateway::RestApi
448 Properties:
449 ApiKeySourceType: HEADER
450 Body: ~
451 Description: "Some Description"
452 FailOnWarnings: false
453 Name: ${opt:stage, self:provider.stage}-some-name
454 EndpointConfiguration:
455 Types:
456 - REGIONAL
457 ApiGatewayDeployment:
458 Type: AWS::ApiGateway::Deployment
459 Properties:
460 RestApiId:
461 Ref: ApiGatewayRestApi
462 StageName: ${opt:stage, self:provider.stage}
463```
464
465```
466serverless deploy --stage=test
467```
468
469```
470serverless deploy --stage=prod
471```
472
473# Approach to a functional test of schema validation
474The plugin works well in combination with the [serverless-plugin-test-helper](https://www.npmjs.com/package/serverless-plugin-test-helper) to automate tests against the deployed api gateway
475
476## Install The plugin test helper package
477
478```shell
479npm install --save-dev serverless-plugin-test-helper
480```
481
482add the plugin as a plugin dependency in your serverless configuration file and configure the plugin according to the [Readme](https://www.npmjs.com/package/serverless-plugin-test-helper)
483```yml
484#./serveless.yml
485plugins:
486 - serverless-plugin-test-helper
487 - serverless-openapi-integration-helper
488
489[...]
490
491resources:
492 Outputs:
493 GatewayUrl: # This is the key that will be used in the generated outputs file
494 Description: This is a helper for functional tests
495 Value: !Join
496 - ''
497 - - 'https://'
498 - !Ref ApiGatewayRestApi
499 - '.execute-api.'
500 - ${opt:region, self:provider.region}
501 - '.amazonaws.com/'
502 - ${opt:stage, self:provider.stage}
503
504 Resources:
505 ApiGatewayRestApi:
506 Type: AWS::ApiGateway::RestApi
507 Properties:
508 ApiKeySourceType: HEADER
509 Body: ~
510 Description: User Registration (${opt:stage, self:provider.stage})
511 FailOnWarnings: false
512 Name: ${opt:stage, self:provider.stage}-gateway
513 EndpointConfiguration:
514 Types:
515 - REGIONAL
516 ApiGatewayDeployment:
517 Type: AWS::ApiGateway::Deployment
518 Properties:
519 RestApiId:
520 Ref: ApiGatewayRestApi
521 StageName: ${opt:stage, self:provider.stage}
522```
523
524## Testing the schema validation
525Add a functional test (e.g. with jest)
526
527```javascript
528//tests/registration.js
529import {getOutput} from 'serverless-plugin-test-helper';
530import axios from 'axios';
531
532axios.defaults.adapter = require('axios/lib/adapters/http'); //Todo
533
534const URL = getOutput('GatewayUrl');
535test('request validation on registration', async () => {
536 expect.assertions(1);
537 const {status} = await axios.post(URL + '/api/v1/user',
538 {
539 "email_address": "test@example.com",
540 "password": "someStrongPassword#"
541 },
542 {
543 headers: {
544 'Content-Type': 'application/json',
545 }
546 });
547 expect(status).toEqual(201);
548});
549
550test('request validation on registration (invalid request)', async () => {
551 expect.assertions(1);
552 try {
553 await axios.post(URL + '/api/v1/user',
554 {
555 "email": "test@example.com"
556 },
557 {
558 headers: {
559 'Content-Type': 'application/json',
560 }
561 });
562 } catch (e) {
563 expect(e.response).toMatchObject({
564 statusText: 'Bad Request',
565 status: 400
566 });
567 }
568});
569```
570Then perform the functional test
571```shell
572serverless deploy --stage=test
573npm test
574serverless remove --stage=test
575```
576
577The command will
578- merge the openapi specification file with the MOCK integration configured before
579- deploy to API Gateway in an isolated TEST infrastructure environment (your other environments will not be affected since we are deploying to a separated gateway)
580- perform the test and verify that schema validation is correct
581- remove all TEST resources if test succeeded
582
583See the **examples** folder for a full working [example](https://github.com/yndlingsfar/serverless-openapi-integration-helper/tree/main/examples)