You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: content/openapi/operations.md
+162Lines changed: 162 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -152,3 +152,165 @@ To add an Extension to a request use the `@ApiExtension()` decorator. The extens
152
152
```typescript
153
153
@ApiExtension('x-foo', { hello: 'world' })
154
154
```
155
+
156
+
#### Advanced: Generic `ApiResponse`
157
+
158
+
With the ability to provide [Raw Definitions](/openapi/types-and-parameters#raw-definitions), we can define Generic schema for Swagger UI. Assume we have the following DTO:
159
+
160
+
```ts
161
+
exportclassPaginatedDto<TData> {
162
+
@ApiProperty()
163
+
total:number;
164
+
165
+
@ApiProperty()
166
+
limit:number;
167
+
168
+
@ApiProperty()
169
+
offset:number;
170
+
171
+
results:TData[];
172
+
}
173
+
```
174
+
175
+
We skip decorating `results` as we will be providing a raw definition for it later. Now, let's define another DTO and name it, for example, `CatDto`, as follows:
176
+
177
+
```ts
178
+
exportclassCatDto {
179
+
@ApiProperty()
180
+
name:string;
181
+
182
+
@ApiProperty()
183
+
age:number;
184
+
185
+
@ApiProperty()
186
+
breed:string;
187
+
}
188
+
```
189
+
190
+
With this in place, we can define a `PaginatedDto<CatDto>` response, as follows:
191
+
192
+
```ts
193
+
@ApiOkResponse({
194
+
schema: {
195
+
allOf: [
196
+
{ $ref: getSchemaPath(PaginatedDto) },
197
+
{
198
+
properties: {
199
+
results: {
200
+
type: 'array',
201
+
items: { $ref: getSchemaPath(CatDto) },
202
+
},
203
+
},
204
+
},
205
+
],
206
+
},
207
+
})
208
+
asyncfindAll(): Promise<PaginatedDto<CatDto>> {}
209
+
```
210
+
211
+
In this example, we specify that the response will have allOf `PaginatedDto` and the `results` property will be of type `Array<CatDto>`.
212
+
213
+
-`getSchemaPath()` function that returns the OpenAPI Schema path from within the OpenAPI Spec File for a given model.
214
+
-`allOf` is a concept that OAS 3 provides to cover various Inheritance related use-cases.
215
+
216
+
Lastly, since `PaginatedDto` is not directly referenced by any controller, the `SwaggerModule` will not be able to generate a corresponding model definition just yet. In this case, we must add it as an [Extra Model](/openapi/types-and-parameters#extra-models). For example, we can use the `@ApiExtraModels()` decorator on the controller level, as follows:
217
+
218
+
```ts
219
+
@Controller('cats')
220
+
@ApiExtraModels(PaginatedDto)
221
+
exportclassCatsController {}
222
+
```
223
+
224
+
If you run Swagger now, the generated `swagger.json` for this specific endpoint should have the followng response defined:
225
+
226
+
```json
227
+
"responses": {
228
+
"200": {
229
+
"description": "",
230
+
"content": {
231
+
"application/json": {
232
+
"schema": {
233
+
"allOf": [
234
+
{
235
+
"$ref": "#/components/schemas/PaginatedDto"
236
+
},
237
+
{
238
+
"properties": {
239
+
"results": {
240
+
"$ref": "#/components/schemas/CatDto"
241
+
}
242
+
}
243
+
}
244
+
]
245
+
}
246
+
}
247
+
}
248
+
}
249
+
}
250
+
```
251
+
252
+
To make it reusable, we can create a custom decorator for `PaginatedDto`, as follows:
> info **Hint**`Type<any>` interface and `applyDecorators` function are imported from the `@nestjs/common` package.
279
+
280
+
With this in place, we can use the custom `@ApiPaginatedResponse()` decorator on our endpoint:
281
+
282
+
```ts
283
+
@ApiPaginatedResponse(CatDto)
284
+
asyncfindAll(): Promise<PaginatedDto<CatDto>> {}
285
+
```
286
+
287
+
For client generation tools, this approach poses an ambiguity in how the `PaginatedResponse<TModel>` is being generated for the client. The following snippet is an example of a client generator result for the above `GET /` endpoint.
As you can see, the **Return Type** here is ambiguous. To workaround this issue, you can add a `title` property to the `schema` for `ApiPaginatedResponse`:
To define additional models that should be inspected by the Swagger module, use the `@ApiExtraModels()` decorator:
242
+
To define additional models that are not directly referenced in your controllers but should be inspected by the Swagger module, use the `@ApiExtraModels()` decorator:
243
243
244
244
```typescript
245
245
@ApiExtraModels(ExtraModel)
246
246
export class CreateCatDto {}
247
247
```
248
248
249
-
Then, you can get the reference (`$ref`) to your model using `getSchemaPath(ExtraModel)`:
249
+
> info **Hint** You only need to use `@ApiExtraModels()` once for a specific model class.
250
+
251
+
Alternatively, you can pass an options object with the `extraModels` property specified to the `SwaggerModule#createDocument()` method, as follows:
0 commit comments