{"id":23469091,"url":"https://github.com/etienne-bechara/bp-nestjs","last_synced_at":"2025-10-29T04:42:05.193Z","repository":{"id":40284014,"uuid":"273654560","full_name":"etienne-bechara/bp-nestjs","owner":"etienne-bechara","description":"Full back-end boilerplate based on NestJS and MikroORM. Written in TypeScript.","archived":false,"fork":false,"pushed_at":"2023-01-11T22:29:30.000Z","size":2156,"stargazers_count":5,"open_issues_count":7,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-28T04:28:35.713Z","etag":null,"topics":["back-end","backend","mikro-orm","nestjs","redis","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/etienne-bechara.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-06-20T06:48:44.000Z","updated_at":"2024-02-07T19:55:08.000Z","dependencies_parsed_at":"2023-02-09T08:46:20.973Z","dependency_job_id":null,"html_url":"https://github.com/etienne-bechara/bp-nestjs","commit_stats":null,"previous_names":[],"tags_count":0,"template":true,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/etienne-bechara%2Fbp-nestjs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/etienne-bechara%2Fbp-nestjs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/etienne-bechara%2Fbp-nestjs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/etienne-bechara%2Fbp-nestjs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/etienne-bechara","download_url":"https://codeload.github.com/etienne-bechara/bp-nestjs/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248906821,"owners_count":21181222,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["back-end","backend","mikro-orm","nestjs","redis","typescript"],"created_at":"2024-12-24T14:59:30.621Z","updated_at":"2025-10-29T04:42:05.128Z","avatar_url":"https://github.com/etienne-bechara.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# NestJS Boilerplate\n\n⚠️ Atenção!\n\nEste repositório foi dividido em vários pacotes menores e não será mais atualizado, confira os componentes em:\n- [@bechara/nestjs-core](https://github.com/etienne-bechara/nestjs-core): Framework principal com agregando logger, http adapter, e outras amenidades ao NestJS.\n- [@bechara/nestjs-orm](https://github.com/etienne-bechara/nestjs-orm): Framework opcional agregando ORM e abstrações para manipular entidades.\n- [@bechara/nestjs-redis](https://github.com/etienne-bechara/nestjs-redis): Plugin opcional para conectar banco de dados Redis.\n- [@bechara/eslint-config-bechara-ts](https://github.com/etienne-bechara/eslint-config-bechara-ts): Múltiplas regras e plugins de lint em TypeScript.\n---\n\nBoilerplate baseado em NestJS com intuito de prover iniciação rápida de projetos em Node.js.\n\n**Guia Rápido**\n\n1\\. Clone este repositório renomeando-o de acordo com seu novo projeto:\n\n```shell\ngit clone https://github.com/etienne-bechara/bp-nestjs.git meu-novo-projeto\ncd meu-novo-projeto\n```\n\n2\\. Execute o script de setup, que irá instalar as dependências e renomear o remote `origin` para `boilerplate`:\n\n```shell\nnpm run boilerplate:setup\n```\n\n2a. Futuramente, caso deseje sincronizar as atualizações deste boilerplate, execute:\n\n```shell\nnpm run boilerplate:udpate\n```\n\n2b. Caso não queira utilizar algum dos serviços opcionais, desinstale-os via:\n\n```shell\nnpm run uninstall:orm\nnpm run uninstall:redis\nnpm run uninstall:sentry\n```\n\n3\\. Suba a aplicação localmente através de:\n\n```shell\nnpm start\n```\n\n---\n\n## Índice\n\n- [Utilização](#utilização)\n  * [Boilerplate](#boilerplate)\n  * [Depuração](#depuraçãoo)\n  * [Dependências](#dependências)\n- [Componentes](#componentes)\n  * [Frameworks](#frameworks)\n  * [Utilitários](#utilitários)\n- [Domain](#domain)\n- [Config](#config)\n  * [Variáveis de Ambiente](#variáveis-de-ambiente)\n  * [Opções do Serviço](#opções-do-serviço)\n- [Entity](#entity)\n- [Modules](#modules)\n- [Controllers](#controllers)\n- [DTO](#dto)\n- [Providers](#providers)\n- [Middlewares](#middlewares)\n- [Interceptors](#interceptors)\n- [Filters](#filters)\n- [Testes](#testes)\n- [Migrations](#migrations)\n- [Templates](#templates)\n  * [API](#api)\n  * [CRUD](#crud)\n\n---\n\n## Utilização\n\nApós seguir os passos do Guia Rápido acima, envie uma requisição `GET` para `localhost:8080`.\n\nO retorno a seguir indica que a aplicação subiu com sucesso:\n\n```json\n{\n    \"error\": 404,\n    \"message\": \"Cannot GET /\",\n    \"details\": {}\n}\n```\n\n### Boilerplate\n\nSempre que quiser atualizar o boilerplate a última versão, execute:\n\n```shell\nnpm run boilerplate:update\n```\n\nCaso tenha alterado arquivos na raiz ou no diretório `/source/core` provavelmente será necessário resolver conflitos de merge antes que possa commitar as alterações.\n\n### Depuração\n\nPor padrão, a aplicação irá expor um sessão de debug na porta `9229`.\n\nAo utilizar a ferramenta `VSCode` como IDE de desevolvimento, basta executar `npm start` e pressionar `F5` para conectar o debugger.\n\nVocê pode criar os `breakpoint` diretamente no arquivo `.ts` que eles serão automaticamente mapeados pelos `.js` em execução.\n\n\n### Dependências\n\nTodas os pacotes que este projeto utiliza estão configurados com a versão exata.\n\nPara realizar atualização dos mesmos, execute um dos scripts a seguir de acordo com o nível de versão que deseja subir.\n\nSiga o padrão Semantic Versioning: `{major}.{minor}.{patch}`\n\n```shell\nnpm run update:patch\nnpm run update:minor\nnpm run update:major\n```\n\n\n\n## Componentes\n\nVários dos frameworks que este projeto é composto são opcionais e podem ser facilmente excluídos para economia de memória RAM durante execução.\n\n\n### Frameworks\n\nDocumentação | Reponsabilidades | Observação \n---|---|---\n[NestJS](https://docs.nestjs.com/) | • Injeção de Dependências\u003cbr\u003e• Inicialização do Servidor (Express)\u003cbr\u003e• Middlewares e Fluxos de Validação\u003cbr\u003e• Filtro Global de Exceções | Irá carregar automaticamente todos os arquivos nomeados como `*.module.ts`.\n[Jest](https://jestjs.io/docs/en/getting-started) | • Testes Unitários\u003cbr\u003e• Testes E2E | Instalado apenas em ambiente de desenvolvimento.\u003cbr\u003eCrie os arquivos de teste no padrão `*.spec.ts`.\n[Sentry](https://www.npmjs.com/package/@sentry/node) | • Monitoramento em Tempo Real\u003cbr\u003e• Rastreio de Exceções | **Opcional**\u003cbr\u003eHabilite configurando a variável `SENTRY_DSN` no `.env`.\n[MikroORM](https://mikro-orm.io/docs/installation) | • Abstração de Banco de Dados como Entidades\u003cbr\u003e• Geração e Execução de Migrations | **Opcional**\u003cbr\u003eHabilite configurando as variáveis `ORM_*` no `.env`.\n[Redis](https://www.npmjs.com/package/redis) | • Armazenamento de Dados do Tipo Chave/Valor\u003cbr\u003e• Compartilhamento de Alta Performance em Serviços Distribuídos | **Opcional**\u003cbr\u003eHabilite configurando as variáveis `REDIS_*` no `.env`.\n\n\n### Utilitários\n\nDocumentação | Reponsabilidades | Utilização \n---|---|---\n[Axios](https://www.npmjs.com/package/axios)    | • Requisições HTTP(s) externas | Foi criado um wrapper em torno da bilblioteca para padronização de exceções.\u003cbr\u003eInjete o serviço `HttpsService` na classe que deseja utilizar.\n[Class Validator](https://www.npmjs.com/package/class-validator) | • Decorators para Validação de Objetos | Dentro da classe, antes da propriedade, utilize um ou mais dos decorators do pacote.\u003cbr\u003eNo caso dos controllers a validação é aplicada automaticamente.\n[Class Transformer](https://www.npmjs.com/package/class-transformer) | • Conversão de Objetos para Classes\u003cbr\u003e• Conversão de Tipo de Propriedades | Utilize um dos métodos do pacote em conjunto com os decorators fornecidos.\u003cbr\u003eEm geral, não será necessário ao menos que altere algo a nível de boilerplate.\n[Moment](https://www.npmjs.com/package/moment) | • Parsing e Formatação de Datas | Inicialize através de `moment()` ou `moment(stringDate)`, e siga os métodos conforme documentação.\n\n\n\n## Domain\n\nÉ o conjunto de todos os componentes que definem um módulo do projeto.\n\nPor exemplo, os usuários, as empresas, a autenticação, a API XPTO externa, etc.\n\nO domínio é representado por uma pasta dentro do diretório `/source`.\n\nOs inclusos no boilerplate estão dentro de `/source/core` para melhor organização.\n\n\n\n## Config\n\nCada domínio, pode ter uma grupo de configurações definidas em um arquivo `*.config.ts`.\n\nAo criar um serviço que extenda a class `AppProvider` (detalhes adiante), é possível obter as recém criadas configurações através do método `this.getConfig()`.\n\nExemplo:\n\n```ts\nexport class MailerService {\n  private config: MailerConfig = this.getConfig();\n}\n```\n\nAs configurações são divididas em duas categorias:\n\n### Variáveis de Ambiente\n\n- Possuem informações sensíveis ou que variam de accordo com o ambiente.\n- São declaradas em modelo chave/valor dentro do arquivo `.env` na raiz do projeto.\n- Todas são inicializadas como `string`.\n- Utilize o decorator `@Transform()` da lib `class-transformer` para convertê-las de tipo.\n- Devem ser declaradas sem valor padrão.\n\nExemplo:\n\n```ts\nexport class AppConfig {\n\n  @IsIn(['DEVELOPMENT', 'STAGING', 'PRODUCTION'])\n  public NODE_ENV: 'DEVELOPMENT' | 'STAGING' | 'PRODUCTION';\n\n  @Transform((v) =\u003e parseInt(v))\n  @IsNumber()\n  public PORT: number;\n\n  @IsOptional()\n  @IsString() @IsNotEmpty()\n  public APP_AUTHORIZATION: string;\n\n}\n```\n\n### Opções do Serviço\n\n- Não possuem informações sensíveis e são idênticas em qualquer ambiente.\n- São declaradas dentro do próprio arquivo `*.config.ts`.\n- Devem ser inicializadas com valor padrão.\n\nExemplo:\n\n```ts\nexport class AppConfig {\n\n  public APP_TIMEOUT: number = 2 * 60 * 1000;\n\n  public APP_CORS_OPTIONS: CorsOptions | boolean = {\n    origin: '*',\n    methods: 'GET, POST, PUT, DELETE',\n    allowedHeaders: 'Content-Type, Accept',\n  };\n\n  public APP_VALIDATION_RULES: ValidationPipeOptions = {\n    whitelist: true,\n    forbidNonWhitelisted: true,\n  };\n\n}\n```\n\n\n\n## Entity\n\n\u003e Conceito aplicável apenas se utilizado o ORM\n\nDefine uma entidade da modelagem de dados, em um banco relacional, podemos considerar como uma tabela.\n\nSão definidas pelos arquivos `*.entity.ts` utilizando decorators para configurar tipo das propriedades e relacionamentos.\n\nRefira-se a [Mikro ORM - Decorators Reference](https://mikro-orm.io/docs/decorators/) para todas as opções.\n\n\n### Predefinidos\n\nClasse | Arquivo | Descrição\n---|---|---\nOrmIdEntity | `ormid.entity.ts` | Extenda essa classe para já incluir uma coluna UUID primária.\nOrmTimestampEntity | `ormtimestamp.entity.ts` | Extenda essa classe para já incluir colunas UUID primária, data de criação e data de atualização.\n\n### Exemplos\n\n```ts\n@Entity({ collection: 'user' })\nexport class UserEntity { \n// utilize extends OrmTimestampEntity acima para simplificar\n\n  @PrimaryKey()\n  public id: string = v4();\n\n  @Property()\n  @Unique()\n  public name!: string;\n\n  @ManyToOne()\n  public team!: TeamEntity;\n\n  @Index()\n  @Property({ columnType: 'timestamp', onUpdate: () =\u003e new Date() })\n  public updated: Date = new Date();\n\n  @Index()\n  @Property({ columnType: 'timestamp' })\n  public created: Date = new Date();\n\n}\n```\n\n\n\n## Modules\n\nUnifica todos os componentes de um domínio em um arquivo `*.module.ts` que será lido e carregado pela aplicação.\n\nNovas classes de módulos devem ser decoradas com `@Module()` e serão carregadas automaticamente quando o serviço iniciar.\n\nA criação de qualquer componente descrito a seguir, sem integrá-lo em um módulo, implicará no mesmo não ter efeito algum.\n\nRefira-se a [Nest JS - Modules](https://docs.nestjs.com/modules) para mais informações.\n\n### Predefinidos\n\nClasse | Arquivo | Descrição\n---|---|---\nAppModule | `app.module.ts` | Ponto de entrada da aplicação, carrega todos os outros módulos.\nHttpsModule | `https.module.ts` | Carrega o serviço abstraído de requisições HTTP(s) baseado em Axios. opcional de envio de e-mails via SMTP.\nOrmModule | `orm.module.ts` | Carrega a camada opcional de abstração para armazenamento em banco de dados.\nRedisModule | `redis.module.ts` | Carrega o serviço opcional para armazenamento chave/valor de alta performance.\n\n\n\n### Exemplos\n\n```ts\n@Module({\n  controllers: [ UserController ],\n  providers: [ UserService ],\n  exports: [ UserService ],\n})\nexport class UserModule { }\n```\n\n\n\n## Controllers\n\nSão responsáveis por receber as requisições HTTP, aplicar validações, e redirecionar os dados para o respectivo serviço de manipulação.\n\nOs controllers seguem o padrão `*.controller.ts`, e devem ser criados dentro da pasta de seu respectivo domínio e importados na propriedade `controllers` do módulo correspondente.\n\nPara definir um controller utilize o decorator `@Controller('domain_name')`.\n\nSendo que `domain_name` será a rota base ao executar requisições HTTP.\n\nRefira-se a [Nest JS - Controllers](https://docs.nestjs.com/controllers) para mais informações.\n\n### Predefinidos\n\nClasse | Arquivo | Descrição\n---|---|---\nOrmController | `ormcontroller.ts` | Extenda essa classe para já criar métodos GET, GET:id, POST, PUT, PUT:id, e DELETE:id.\u003cbr\u003eAplicável apenas se o ORM estiver habilitado.\n\n### Exemplos\n\nCustomizado:\n\n```ts\n@Controller('user')\nexport class UserController {\n\n  public constructor(private readonly userService: UserService) { }\n\n  @Get(':id')\n  public async getUser(@Param('id') id: string): Promise\u003cUserData\u003e {\n    return this.userService.readUser(id);\n  }\n  \n}\n```\n\nBasedo em um serviço de ORM:\n\n```ts\n@Controller('user')\nexport class UserController extends OrmController\u003cUserEntity\u003e {\n\n  public constructor(private readonly userService: UserService) {\n    super(userService);\n\n    this.options = {\n      dto: {\n        read: UserReadDto,\n        create: UserCreateDto,\n        update: UserUpdateDto,\n      },\n    };\n\n  }\n\n}\n```\n\n\n## DTO\n\nData Transfer Objects definem a estrutura de como os dados são transferidos.\n\nAo criar controllers que recebem dados, você pode injetá-los em argumentos via decorators `@Body()`, `@Query()` e `@Param()`.\n\nUma vez que definir o tipo deste argumentos como uma classe DTO decorada com opções da biblioteca `class-validator`, suas requisições serão automaticamente validadas.\n\nCrie-os em pastas `*.dto` em arquivos sobre a que método se referem, por exemplo `*.create.dto.ts` ou `*.update.dto.ts`.\n\nRefira-se a [Nest JS - Auto Validation](https://docs.nestjs.com/techniques/validation#auto-validation) para mais informações.\n\nLista completa de decorators disponíveis em [Class Validator - Decorator Reference](https://github.com/typestack/class-validator#validation-decorators).\n\n### Exemplos\n\nDTO para criação de usuário:\n\n```ts\nexport class UserCreateDto {\n\n  @IsString() @IsNotEmpty()\n  public name: string;\n\n  @IsNumber() @Min(1)\n  public age: string;\n\n}\n```\n\nDefinição de tipo no controller:\n\n```ts\n@Controller('user')\nexport class UserController {\n\n  public constructor(private readonly userService: UserService) { }\n\n  @Post()\n  // O fato de definirmos UserCreateDto a seguir irá validar a requisição automaticamente\n  public async postUser(@Body() body: UserCreateDto): Promise\u003cUserData\u003e {\n    return this.userService.createUser(body);\n  }\n  \n}\n```\n\n\n\n## Providers\n\nServiços são componentes que executam um ou mais dentre extração, transformação e carregamento de dados.\n\nA instanciação de suas classes são gerenciadas pela injeção de depências do framwork, por isso devem ser decorados com `@Injectable()`.\n\nEles podem ter vários tipos includindo Middlewares, Interceptors, Filters, etc, explicados mais adiante.\n\nPara o serviço principal do seu domínio, utilize o padrão `*.service.ts` de nomenclatura e importe-o na propriedade `providers` do módulo respectivo.\n\nCaso deseje que outros módulos tenha acesso ao seu serviço, é necessário exportá-lo na propriedade `exports`\n\nRefira-se a [Nest JS - Providers](https://docs.nestjs.com/providers) para mais informações.\n\n\n### Predefinidos\n\nClasse | Arquivo | Descrição\n---|---|---\nAppProvider | `abstract.provider.ts` | Extenda essa classe para já ter acesso ao logger, variáveis de ambiente e método de retry.\nOrmService | `ormservice.ts` | Extenda essa classe para já ter acesso a métodos de manipulação de dados via ORM com gerenciamento de exeções nas queries.\nHttpsService | `https.service.ts` | Wrapper sobre o Axios para padronizar exceções HTTP e adicionar amenidades.\nLoggerService | `logger.service.ts` | Disponível via AppProvider, realiza integração com Sentry e imprime no console durante desenvolvimento.\nRedisService | `redis.service.ts` | Wrapper sobre o redis para ler e persistir dados chave/valor em cloud.\n\n### Exemplos\n\nCustomizado:\n\n```ts\n@Injectable()\nexport class UserService {\n\n  /** Implemente seus métodos */\n\n  public async userHello(): Promise\u003cvoid\u003e {\n    this.logger.debug('hello world');\n  }\n\n}\n```\n\nBaseado em serviço ORM:\n\n```ts\n@Injectable()\nexport class UserService extends OrmService\u003cUserEntity\u003e {\n\n  public constructor(\n    @InjectRepository(UserEntity)\n    private readonly userRepository: EntityRepository\u003cUserEntity\u003e,\n  ) {\n    super(userRepository, {\n      uniqueKey: [ 'name' ],\n      populate: [ 'team' ],\n    });\n  }\n\n}\n```\n\n## Middlewares\n\nExecutam procedimentos logo que uma requisição HTTP entra e antes de chegar nos interceptors ou controllers.\n\nDevem ser decoradas com `@Injectable()`, implementar `NestMiddleware` e serem aplicadas via `consumer` a nível de módulo.\n\nRefira-se a [Nest JS - Middleware](https://docs.nestjs.com/middleware) para mais informações.\n\n### Predefinidos\n\nClasse | Arquivo | Descrição\n---|---|---\nAppAuthMiddleware | `app.metadata.middleware.ts` | Extrai o IP e User Agent da requisição e os separa em uma propriedade de metadados\n\n### Exemplos\n\nImplementação:\n```ts\nimport { Injectable, NestMiddleware } from '@nestjs/common';\nimport { Request, Response } from '../app.interface';\n\n@Injectable()\nexport class AppMetadataMiddleware implements NestMiddleware {\n\n  public async use(req: Request, res: Response, next: any): Promise\u003cvoid\u003e {\n    req['metadata'] = {\n      ip: requestIp.getClientIp(req) || null,\n      userAgent: req.headers ? req.headers['user-agent'] : null,\n    };\n    next();\n  }\n\n}\n```\n\nImportação:\n\n```ts\nexport class AppModule {\n\n  public configure(consumer: MiddlewareConsumer): void {\n    consumer\n      .apply(\n        // Aplique quantos quiser em ordem\n        AppMetadataMiddleware,\n      )\n      // Você pode escolher as rotas com:\n      // .forRoutes({ method, path }, { method, path });\n      .forRoutes('*');\n  }\n\n}\n```\n\n\n\n## Interceptors\n\nPermitem que manipule dados de uma mesma requisição antes de ela atingir um controller bem como após ser tratada por ele.\n\nÚteis caso precise rastrear a trajetória de uma requisição ou aplicar de maneira unifica algo durante seu retorno.\n\nSeguem o padrão `*.interceptor.ts`, e devem ser decorados por `Injectable()` bem como importados no respectivo módulo.\n\nTambém devem implementar a classe `NestInterceptor` e retornar um `Observable` o que permite rastrear a requisição e utilizar métodos `rxjs` em seu témino.\n\nRefira-se a [Nest JS - Interceptors](https://docs.nestjs.com/interceptors) para mais informações.\n\n### Predefinidos\n\nClasse | Arquivo | Descrição\n---|---|---\nAppLoggerInterceptor | `app.logger.interceptor.ts` | Extrai o IP da requisição bem faz o log da entrada e saída da requisição.\nAbstractEntityInterceptor | `ormentity.interceptor.ts` | Executa o método `toJSON()` das entidades antes de retorná-las. Aplicável apenas se utilizado o ORM.\n\n### Exemplo\n\nImplementação:\n\n```ts\n@Injectable()\nexport class AppLoggerInterceptor implements NestInterceptor {\n\n  public intercept(context: ExecutionContext, next: CallHandler): Observable\u003cany\u003e {\n    const req: AppRequest = context.switchToHttp().getRequest();\n\n    this.logger.server(`Incoming ${req.url}`);\n\n    return next\n      .handle()\n      .pipe(\n        // Utilize dentro do .pipe qualquer método rxjs\n        finalize(() =\u003e {\n          const res: AppResponse = context.switchToHttp().getResponse();\n          this.logger.server(`Finished ${req.url} with status ${res.statusCode}`);\n        }),\n      );\n  }\n\n}\n```\n\nImportação:\n\n```ts\n@Module({\n  providers: [\n    { provide: APP_INTERCEPTOR, useClass: AppLoggerInterceptor },\n  ],\n})\nexport class AppModule { }\n```\n\n\n## Filters\n\nFiltros são decorados com `@Catch()` e servem o propósito de capturar execeções durante execução do contexto.\n\nNeste boilerplate utilizamos um a nível global para padronização de retorno HTTP, mas eles podem ser individualizados a nível de módulo.\n\nRefira-se a [Nest JS - Exception Filters](https://docs.nestjs.com/exception-filters) para mais informações.\n\n### Predefinidos\n\nClasse | Arquivo | Descrição\n---|---|---\nAppFilter | `app.filter.ts` | Padroniza o retorno HTTP em caso de exceções.\n\n\n\n## Testes\n\nOs testes são baseados no framework Jest, todavia para total isolamento nas execuções, o NestJS provê um pacote para compilação individual de módulos temporários `@nestjs/testing`.\n\nPara usufruir desta funcionalidade, configure seus testes com um método `beforeEach()` implementando `createTestingModule()` conforme exemplo a seguir:\n\n```ts\nimport { Test } from '@nestjs/testing';\nimport { RedisService } from './redis.service';\n\ndescribe('RedisService', () =\u003e {\n  const rng = Math.random();\n  let redisService: RedisService;\n\n  beforeAll(async() =\u003e {\n    const testModule = await Test.createTestingModule({\n      providers: [ RedisService ],\n    }).compile();\n\n    redisService = testModule.get(RedisService);\n  });\n\n  describe('setKey', () =\u003e {\n    it('should persist a random number', async() =\u003e {\n      expect(await redisService.setKey('TEST_KEY', { rng }, 10 * 1000))\n        .toBeUndefined();\n    });\n  });\n\n  describe('getKey', () =\u003e {\n    it('should read persisted random number', async() =\u003e {\n      expect(await redisService.getKey('TEST_KEY'))\n        .toMatchObject({ rng });\n    });\n  });\n});\n```\n\nAgora basta executar `npm run test` e todos os testes descritos em arquivos `*.spec.ts` serão aplicados.\n\n\n\n## Migrations\n\n\u003ePara utilizar migrations com versionamento e rollback refira-se a documentação oficial: [Mikro ORM - Migrations](https://mikro-orm.io/docs/migrations/)\n\nEste boilerplate permite sincronizar a modelagem atual com as entidades definidas nos arquivos `*.entity.ts`.\n\nPor padrão, é possível possuir até três ambientes configurados em arquivos `.env` separados sendo:\n\n```bash\n.env              # Desenvolvimento\n.env.staging      # Homologação\n.env.production   # Produção\n```\n\nPara realizar a migração de sincronismo execute:\n\n```bash\nnpm run orm:sync:dev  # Utiliza arquivo .env\nnpm run orm:sync:stg  # Utiliza arquivo .env.staging\nnpm run orm:sync:prd  # Utiliza arquivo .env.production\n```\n\nCaso prefira apenas visualizar a migração e não executá-la, substitua o script `orm:sync` por `orm:dump`. As queries serão impressas no console.\n\n\n\n## Templates\n\nCriar serviços, controllers e DTOs de algo repetitivo pode ser bastante tedioso, sendo assim foi desenvolvido uma maneira mais simples para realizar estas implementações.\n\n### API\n\nCria todos os arquivos recomendados para implementação de um serviço de API externo.\n\nDado um domínio de sua escolha, por exemplo: `gmaps`, execute o script:\n\n```\nnpm run template:api -- -n gmaps\n```\n\nA seguinte estrutura de arquivos será criada dentro de `/source`:\n\n```\ngmaps\n|- gmaps.dto\n   | - index.ts\n|- gmaps.interface\n   | - index.ts\n|- gmaps.service.ts\n|- gmaps.config.ts\n```\n\nAgora, por padrão, as variáveis de ambiente `GMAPS_HOST` e `GMAPS_AUTH` serão mandatórias. Você pode configurar a validação no arquivo `gmaps.config.ts`.\n\nA estratégia de autenticação do modelo é colocar o `*_AUTH` no header `Authorization`. Dependendo do serviço será necessário modificar.\n\n\n\n### CRUD\n\nCria todos os arquivos recomendados para implementação de uma entidade com métodos HTTP de GET, GET:id, POST, PUT, PUT:id, e DELETE:id.\n\nDado um domínio de sua escolha, por exemplo: `user`, execute o script:\n\n```\nnpm run template:crud -- -n user\n```\n\nA seguinte estrutura de arquivos será criada dentro de `/source`:\n\n```\nuser\n|- user.dto\n   | - index.ts\n   | - user.create.dto.ts\n   | - user.read.dto.ts\n   | - user.update.dto.ts\n|- user.controller.ts\n|- user.entity.ts\n|- user.module.ts\n|- user.service.ts\n```\n\nAgora é só definir a entidade em `user.entity.ts` e configurar a validação dos dtos que todos os métodos estarão implementados.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fetienne-bechara%2Fbp-nestjs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fetienne-bechara%2Fbp-nestjs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fetienne-bechara%2Fbp-nestjs/lists"}