|
1 | | -# Nest AWS Serverless Tools |
| 1 | +# Nest OpenAPI Tools |
2 | 2 |
|
3 | | -In alpha mode. Maybe pre-alpha. Docs coming soon. |
| 3 | +This library provides basic tooling around OpenAPI integrations with NestJS. |
4 | 4 |
|
5 | | -#### Installation |
| 5 | +# Installation |
6 | 6 |
|
7 | | -If you did not use the `init` process from the `@aws-serverless-tools/cli` package, the tools package can be installed directly: |
8 | | - |
9 | | -`npm install --save @aws-serverless-tools/cli` |
10 | | - |
11 | | -### AwsServerlessToolsModule |
12 | | - |
13 | | -This module simplifies the following: |
14 | | - |
15 | | -1. Enabling an OpenAPI documentation web server side-by-side with your API (at `/apidocs` by default). |
16 | | -2. Generating an OpenAPI specification file. |
17 | | -3. Generating an Angular client module. |
18 | | - |
19 | | -#### Setup |
| 7 | +```bash |
| 8 | +npm install -g @openapitools/openapi-generator-cli # Used to generate OpenAPI clients from documents. |
| 9 | +npm install --save nest-openapi-tools @nestjs/swagger swagger-ui-express |
| 10 | +``` |
20 | 11 |
|
21 | | -##### Module import |
| 12 | +# Usage |
22 | 13 |
|
23 | | -First, import the module into your AppModule. |
| 14 | +## OpenApiNestFactory |
24 | 15 |
|
25 | | -```ts |
26 | | -// app.module.ts |
27 | | -import { Module } from '@nestjs/common'; |
28 | | -import { AppController } from './app.controller'; |
29 | | -import { AppService } from './app.service'; |
30 | | -import { AwsServerlessToolsModule } from 'nest-aws-serverless-tools'; |
31 | | - |
32 | | -@Module({ |
33 | | - imports: [ |
34 | | - AwsServerlessToolsModule, |
35 | | - ], |
36 | | - controllers: [AppController], |
37 | | - providers: [AppService], |
38 | | -}) |
39 | | -export class AppModule {} |
40 | | -``` |
| 16 | +The OpenApiNestFactory simplifies the process of: |
41 | 17 |
|
42 | | -Once imported, update the `main.ts` file to retrieve the `ApiGatewayOpenApi` service and start the document server. |
| 18 | +1. Generating an OpenAPI file. |
| 19 | +2. Generating a client project (i.e. an Angular client module). |
| 20 | +3. Starting up the OpenAPI documentation web server. |
43 | 21 |
|
44 | | -##### Generation - Option A: Always generate on bootstrap |
| 22 | +### How to use |
45 | 23 |
|
46 | | -With this approach, every build will update the OpenAPI specification file and generate an Angular client. |
| 24 | +To leverage this functionality, swap out the `NestFactory` provided by Nest with the `OpenApiNestFactory.configure()` call as demonstrated below. |
47 | 25 |
|
48 | 26 | ```ts |
49 | | -// main.ts |
50 | | - |
| 27 | +// main.ts - BEFORE |
51 | 28 | import { NestFactory } from '@nestjs/core'; |
52 | 29 | import { AppModule } from './app.module'; |
53 | | -import { ApiGatewayOpenApi } from 'nest-aws-serverless-tools'; |
54 | 30 |
|
55 | 31 | async function bootstrap() { |
56 | 32 | const app = await NestFactory.create(AppModule); |
57 | | - |
58 | | - const openApi = await app.get(ApiGatewayOpenApi) |
59 | | - .setNestAppContext(app) |
60 | | - .enableDocumentationWebServer(); |
61 | | - await openApi.generateOpenApiFile(); |
62 | | - await openApi.generateAngularClient(); |
63 | | - |
64 | 33 | await app.listen(3000); |
65 | 34 | } |
66 | 35 | bootstrap(); |
67 | 36 | ``` |
68 | 37 |
|
69 | | -##### Generation - Option B: Only generate when the --openapi-generate flag is used (i.e. in `npm run openapi`) |
70 | | - |
71 | | -This is the recommended option. This will generate the OpenAPI specification file and Angular client but only when --openapi-generate is passed to the command. |
72 | | - |
73 | 38 | ```ts |
74 | | -// main.ts |
| 39 | +// main.ts - AFTER |
75 | 40 | import { NestFactory } from '@nestjs/core'; |
76 | 41 | import { AppModule } from './app.module'; |
77 | | -import { ApiGatewayOpenApi } from 'nest-aws-serverless-tools'; |
| 42 | +import { OpenApiNestFactory } from '@aws-serverless-tools/nest'; |
78 | 43 |
|
79 | 44 | async function bootstrap() { |
80 | 45 | const app = await NestFactory.create(AppModule); |
81 | 46 |
|
82 | | - const openApi = await app.get(ApiGatewayOpenApi) |
83 | | - .setNestAppContext(app) |
84 | | - .enableDocumentationWebServer(); |
| 47 | + await OpenApiNestFactory.configure(app, { |
| 48 | + documentBuilder: new DocumentBuilder() |
| 49 | + .setDescription('My API') |
| 50 | + .addBearerAuth(), |
| 51 | + webServerOptions: { |
| 52 | + enabled: true, |
| 53 | + path: 'api-docs', |
| 54 | + }, |
| 55 | + fileGeneratorOptions: { |
| 56 | + enabled: true, |
| 57 | + outputFilePath: './openapi.yaml', // or ./openapi.json |
| 58 | + }, |
| 59 | + clientGeneratorOptions: { |
| 60 | + enabled: true, |
| 61 | + type: 'typescript-axios', |
| 62 | + outputFolderPath: '../typescript-api-client/src', |
| 63 | + additionalProperties: |
| 64 | + 'apiPackage=clients,modelPackage=models,withoutPrefixEnums=true,withSeparateModelsAndApi=true', |
| 65 | + openApiFilePath: './openapi.yaml', // or ./openapi.json |
| 66 | + skipValidation: true, // optional, false by default |
| 67 | + }, |
| 68 | + }, { |
| 69 | + operationIdFactory: (c: string, method: string) => method, |
| 70 | + }); |
85 | 71 |
|
86 | | - if (!(await openApi.handleGenerateCommand(true, true))) { |
87 | | - await app.listen(3000); |
88 | | - } |
| 72 | + await app.listen(3000); |
89 | 73 | } |
90 | 74 | bootstrap(); |
91 | 75 | ``` |
92 | 76 |
|
93 | | -#### Configuration |
94 | | - |
95 | | -In `package.json`, there are the following configuration options pre-enabled: |
| 77 | +In this example, we will (a) enable the documentation web server at http://localhost:3000, (b) generate the OpenAPI document at `./openapi.yaml`, and lastly (c) generate a TypeScript API client. |
96 | 78 |
|
97 | | -```json |
98 | | -{ |
99 | | - "openApi": { |
100 | | - "filePath": "./cfn/openapi.yaml", |
101 | | - "clientOutputFolderPath": "./angular-client/", |
102 | | - "clientAdditionalProperties": "apiModulePrefix=KerryTest,fileNaming=kebab-case,stringEnums=true,taggedUnions=true" |
103 | | - } |
104 | | -} |
105 | | -``` |
106 | | - |
107 | | -* **docsWebServerRoot**: The root at which to run the OpenAPI webserver. Default: "apidocs". |
108 | | -* **filePath**: The path to the OpenAPI specification file. |
109 | | -* **apiBaseUrl**: The host or base URL to the API for the Angular client to use by default. |
110 | | -* **clientOutputFolderPath**: The relative path to the Angular client output.; |
111 | | -* **clientModulePrefix**: The prefix of the Angular module, i.e. `${clientModulePrefix}ApiModule`. |
112 | | -* **clientAdditionalProperties**: Additional Angular client generation configuration. See https://openapi-generator.tech/docs/generators/typescript-angular/ for more options. |
113 | | - |
114 | | - |
115 | | -### CloudFormationLambdaParametersConfig |
116 | | - |
117 | | -When running your Lambda in AWS, you'll likely environment variables for configuration. However, maintaining these variables in `process.env` can be cumbersome. |
118 | | - |
119 | | -`CloudFormationLambdaParametersConfig` is a loader for the `@nestjs/config` package to look at your CloudFormation file, cross-reference your Lambda environment variables to a specified parameters file, and make them available via the `nestjs/config` ConfigService. |
120 | | - |
121 | | -Note that since this uses `@nestjs/config`, you are free to use `.env` files or any other configuration you see fit for secrets or other configuration options not managed via parameters. |
122 | | - |
123 | | -#### Setup |
124 | | - |
125 | | -##### ConfigModule Import |
126 | | - |
127 | | -Add the `@nestjs/config` ConfigModule to your AppModule imports. |
128 | | - |
129 | | -```ts |
130 | | -// main.ts |
131 | | -import { Module } from '@nestjs/common'; |
132 | | -import { ConfigModule } from '@nestjs/config'; |
133 | | -import { AppController } from './app.controller'; |
134 | | -import { AppService } from './app.service'; |
135 | | -import { AwsServerlessToolsModule, CloudFormationLambdaParametersConfig } from 'nest-aws-serverless-tools'; |
136 | | - |
137 | | -@Module({ |
138 | | - imports: [ |
139 | | - AwsServerlessToolsModule, |
140 | | - ConfigModule.forRoot({ |
141 | | - load: [CloudFormationLambdaParametersConfig], |
142 | | - isGlobal: true, |
143 | | - }), |
144 | | - ], |
145 | | - controllers: [AppController], |
146 | | - providers: [AppService], |
147 | | -}) |
148 | | -export class AppModule {} |
149 | | -``` |
| 79 | +*Note*, file generation and client generation should be disabled in production as they are costly to startup time. |
150 | 80 |
|
151 | | -## Stay in touch |
| 81 | +### Generator Options |
152 | 82 |
|
153 | | -- Author - [Kerry Ritter](http://kerryritter.com) |
154 | | -- Twitter - [@kerryritter](https://twitter.com/kerryritter) |
| 83 | +This project leverages the [OpenAPITools/openapi-generator](https://github.com/OpenAPITools/openapi-generator) project via the npm package, `@openapitools/openapi-generator-cli` which is required to be installed globally. Accordingly, any client generators and configuration supported by this project are usable via Nest OpenAPI Tools. |
155 | 84 |
|
156 | | -## License |
| 85 | +# Stay in touch |
157 | 86 |
|
158 | | - Nest is [MIT licensed](LICENSE). |
| 87 | +Author - Kerry Ritter, BeerMoneyDev |
| 88 | +Website - https://www.kerryritter.com/, https://www.beermoney.dev/ |
0 commit comments