Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/igrek8/nestjs-typed-responses
Allows implementation of polymorphism in OAS and exports nest.js exceptions as swagger schemes
https://github.com/igrek8/nestjs-typed-responses
nestjs openapi openapi3 swagger
Last synced: 2 months ago
JSON representation
Allows implementation of polymorphism in OAS and exports nest.js exceptions as swagger schemes
- Host: GitHub
- URL: https://github.com/igrek8/nestjs-typed-responses
- Owner: igrek8
- License: mit
- Created: 2022-10-16T13:39:35.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2024-04-19T20:43:55.000Z (9 months ago)
- Last Synced: 2024-11-17T11:37:35.428Z (2 months ago)
- Topics: nestjs, openapi, openapi3, swagger
- Language: TypeScript
- Homepage:
- Size: 2.65 MB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Codeowners: .github/CODEOWNERS
Awesome Lists containing this project
README
# [Handle polymorphic responses](https://swagger.io/docs/specification/data-models/inheritance-and-polymorphism) in Nest.js OpenAPI
Enables OpenAPI v3 polymorphism using `__type` metafield to resolve different exceptions or responses within the same HTTP code response group.
[![NPM](https://badgen.net/npm/v/nestjs-typed-responses)](https://www.npmjs.com/nestjs-typed-responses)
[![Coverage](https://codecov.io/gh/igrek8/nestjs-typed-responses/branch/main/graph/badge.svg)](https://codecov.io/gh/igrek8/nestjs-typed-responses)
![Release](https://badgen.net/github/checks/igrek8/nestjs-typed-responses)
![License](https://badgen.net/github/license/igrek8/nestjs-typed-responses)## Installation
```bash
npm install --save nestjs-typed-responsesyarn add nestjs-typed-responses
```## OpenAPI
![Swagger](./media/swagger.png)
## Usage
```ts
import { ConsoleLogger, Controller, HttpCode, HttpStatus, Module, Post, ValidationPipe } from '@nestjs/common';
import { APP_PIPE, NestFactory } from '@nestjs/core';
import {
ApiBadRequestResponse,
ApiExtraModels,
ApiForbiddenResponse,
ApiOkResponse,
ApiProperty,
DocumentBuilder,
refs,
SwaggerModule,
} from '@nestjs/swagger';
import { Expose } from 'class-transformer';
import { IsDateString, IsString } from 'class-validator';
import {
ApiTypeMetafield,
BadRequestException,
ServiceUnavailableException,
TypedDataTransferObject,
TypedResponseModule,
ValidationException,
} from 'nestjs-typed-responses';class MyResponse implements TypedDataTransferObject {
// ApiTypeMetafield must be defined to specify serializable type
@ApiTypeMetafield('MyResponse')
__type = 'MyResponse';// It is not required to apply @Expose decorator (per configuration)
@ApiProperty()
@IsString()
data!: string;constructor(props: Omit) {
Object.assign(this, props);
}
}class MaintenanceException extends ServiceUnavailableException implements TypedDataTransferObject {
// ApiTypeMetafield must be defined to specify serializable type
@ApiTypeMetafield('MaintenanceException')
override __type = 'MaintenanceException';// @Expose must be used explicitly in error classes as only such fields will be exposed
@Expose()
@ApiProperty({
example: '2022-12-31T11:00:00.000Z',
description: 'There is a maintenance on the server',
})
@IsDateString()
operationalAt!: Date;
}@Controller()
@ApiExtraModels(ValidationException, BadRequestException)
class AppController {
@Post()
@HttpCode(HttpStatus.OK)
@ApiOkResponse({ type: MyResponse })
@ApiForbiddenResponse({ type: MaintenanceException })
// Polymorphism https://swagger.io/docs/specification/data-models/inheritance-and-polymorphism/
@ApiBadRequestResponse({ schema: { oneOf: refs(ValidationException, BadRequestException) } })
demo(): MyResponse {
return new MyResponse({
data: 'Hello!',
});
}
}@Module({
providers: [
{
provide: APP_PIPE,
useValue: new ValidationPipe({
exceptionFactory: ValidationException.exceptionFactory,
}),
},
],
imports: [TypedResponseModule],
controllers: [AppController],
})
class AppModule {}async function bootstrap() {
const app = await NestFactory.create(AppModule);
const config = new DocumentBuilder().build();
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('/', app, document);
await app.listen(3000);
}
bootstrap();
```