Confira neste artigo: com a inclusรฃo de cada vez mais software nas empresas, como mantรช-lo escalรกvel, seguro e com qualidade.
Tempo de Leitura: 4 minutos
Durante a pandemia as empresas tiveram que inovar e adotar posturas mais tecnolรณgicas e incluir cada vez mais softwares em seus processos de negรณcio.
Com isso, entre os desenvolvedores, hรก muita preocupaรงรฃo em como manter o software escalรกvel, seguro e com qualidade.
Neste artigo, veremos como pensar e desenvolver um software baseado nos princรญpios SOLID e como podemos aplicar o primeiro princรญpio (Single Responsibility Principle) e separar a camada de acesso ao banco de dados do restante da aplicaรงรฃo, utilizando NestJS.
Afinal, o que รฉ SOLID?
O princรญpio SOLID nada mais รฉ do que cinco princรญpios observados na orientaรงรฃo a objetos e design(ou tambรฉm conhecido como POO - Programaรงรฃo Orientada a Objetos) de cรณdigo que foram abordados no artigo The Principles of OOD - Robert C Martin (a.k.a Uncle Bob).
O SOLID ajuda o programador a manter a qualidade de software e a escrever cรณdigos mais limpos, separando as responsabilidades, facilitando a refatoraรงรฃo e estimula o aproveitamento de cรณdigo.
SOLID: Os cinco princรญpios da POO
- S - Single Responsibility Principle (Princรญpio da Responsabilidade รnica)
- O - Open-closed Principle (Princรญpio aberto-fechado)
- L - Liskov Substitution Principle (Princรญpio de Substituiรงรฃo de Liskov)
- I - Interface Segregation Principle (Princรญpio da Segregaรงรฃo de Interface)
- D - Dependency Inversion Principle (Princรญpio da inversรฃo de dependรชncia
Neste artigo, abordaremos somente o primeiro princรญpio e ensinar vocรช a realizar a separaรงรฃo de responsabilidade utilizando o NestJS.
Single Responsibility Principle (Princรญpio da Responsabilidade รnica)
Legenda: ร determinado que uma classe deve ter apenas um objetivo. | Imagem: Unsplash
O princรญpio da responsabilidade รบnica determina que uma classe deve ter apenas um objetivo (ou responsabilidade), ou seja, ela deve executar apenas uma รบnica funรงรฃo dentro do seu escopo.
Na prรกtica funciona da seguinte forma: imagine que vocรช vรก a um restaurante e neste restaurante vocรช encontra vรกrios tipos de funcionรกrios: os garรงons, o cozinheiro, o caixa e assim por diante.
Cada funcionรกrio deste restaurante executa funรงรตes que tem tudo a ver com sua responsabilidade:
- Cozinheiro: faz o preparo dos alimentos do restaurante.
- Garรงom: รฉ responsรกvel por anotar o seu pedido e entregรก-lo a vocรช.
- Caixa: recebe o pagamento da sua comanda.
- e assim por diante.ย
Certo, e como eu implemento este princรญpio em meu projeto Nest?
Vamos agora iniciar o nosso projeto em Nest. Para este artigo, faremos uma aplicaรงรฃo que contรฉm um cadastro de usuรกrios.
Antes de comeรงarmos, รฉ necessรกrio que tenha instalado na sua mรกquina o NodeJS e um gerenciador de pacotes de sua preferรชncia, podendo ser o npm ou o yarn.
Tambรฉm รฉ necessรกrio instalar o NestJS CLI, que serรก responsรกvel por instalar e configurar as dependรชncias necessรกrias para rodar nossa aplicaรงรฃo.
No terminal, rode o comando:
nest new user-api
O NestJS irรก criar o projeto e solicitar qual gerenciador de dependรชncias serรก utilizado para instalar as dependรชncias:
Fonte: print screen do terminal de Raul Neto
Fonte: print screen do terminal de Raul Neto
Com o processo finalizado, iremos abrir o Visual Studio Code e iniciar nossa configuraรงรฃo.
Abaixo temos a estrutura que o Nest criou para darmos andamento ao projeto:
Fonte: print screen do terminal de Raul Neto
ย
Configurando o TypeORM
Para realizarmos a configuraรงรฃo do TypeORM no projeto, primeiro precisamos instalar os pacotes @nestjs/typeorm, typeorm e pg (usaremos o banco de dados PostgreSQL). Para isso, basta executar o seguinte comando:
$ yarn add @nestjs/typeorm typeorm pg
Em seguida, criaremos uma pasta config e incluiremos nela um arquivo database.ts, com as seguintes configuraรงรตes:
import * as dotenv from 'dotenv'; import { ConnectionOptions } from 'typeorm'; dotenv.config(); const { NODE_ENV, DB_USERNAME_DEVELOPMENT, DB_PASSWORD_DEVELOPMENT, DB_NAME_DEVELOPMENT, DB_HOSTNAME_DEVELOPMENT, DB_PORT_DEVELOPMENT, DB_USERNAME_TEST, DB_PASSWORD_TEST, DB_NAME_TEST, DB_HOSTNAME_TEST, DB_PORT_TEST, DB_USERNAME_PRODUCTION, DB_PASSWORD_PRODUCTION, DB_NAME_PRODUCTION, DB_PORT_PRODUCTION, DB_HOSTNAME_PRODUCTION, DB_USERNAME_SANDBOX, DB_PASSWORD_SANDBOX, DB_NAME_SANDBOX, DB_PORT_SANDBOX, DB_HOSTNAME_SANDBOX, } = process.env; const config: Record<string, any> = { development: { type: 'postgres', username: DB_USERNAME_DEVELOPMENT, password: DB_PASSWORD_DEVELOPMENT, database: DB_NAME_DEVELOPMENT, host: DB_HOSTNAME_DEVELOPMENT, port: parseInt(DB_PORT_DEVELOPMENT || '5434', 10), }, test: { type: 'postgres', username: DB_USERNAME_TEST, password: DB_PASSWORD_TEST, database: DB_NAME_TEST, host: DB_HOSTNAME_TEST, port: parseInt(DB_PORT_TEST || '5434', 10), }, sandbox: { type: 'postgres', username: DB_USERNAME_SANDBOX, password: DB_PASSWORD_SANDBOX, database: DB_NAME_SANDBOX, port: parseInt(DB_PORT_SANDBOX || '5432', 10), host: DB_HOSTNAME_SANDBOX, }, production: { type: 'postgres', username: DB_USERNAME_PRODUCTION, password: DB_PASSWORD_PRODUCTION, database: DB_NAME_PRODUCTION, port: parseInt(DB_PORT_PRODUCTION || '5432', 10), host: DB_HOSTNAME_PRODUCTION, }, }; export const getConfig = (): ConnectionOptions => config[NODE_ENV || 'development'];
Em seguida, acessaremos o arquivo app.module.ts e incluiremos as seguintes configuraรงรตes:
import { Module } from '@nestjs/common'; import { getConfig } from './config/database'; import { TypeOrmModule } from '@nestjs/typeorm'; @Module({ imports: [ TypeOrmModule.forRoot({ ...getConfig(), entities: [], }), ], controllers: [], providers: [], }) export class AppModule {}
Agora criaremos nossa primeira entidade, a entidade Usuรกrio. Na pasta entities, crie um arquivo User.ts, com as seguintes configuraรงรตes:
import { Column, CreateDateColumn, Entity, PrimaryColumn, UpdateDateColumn, } from 'typeorm'; import { v4 as uuid } from 'uuid'; @Entity('users') export class User { @PrimaryColumn() id: string; @Column() name: string; @Column() username: string; @Column() password: string; @Column({ name: 'is_app' }) isApp: boolean; @CreateDateColumn({ name: 'created_at' }) createdAt: Date; @UpdateDateColumn({ name: 'updated_at' }) updatedAt: Date; constructor() { if (!this.id) this.id = uuid(); } }
Agora criaremos o nosso repositรณrio, que deve estar em uma camada separada da camada de lรณgica de negรณcio.
Na pasta repositories, crie o arquivo UserRepository.ts com as seguintes configuraรงรตes:
import { Repository } from 'typeorm'; import { InjectRepository } from '@nestjs/typeorm'; export class UserRepository { constructor( @InjectRepository(User) private repository: Repository<User>, ) {} async create(): Promise<User> { /* * Cรณdigo para cadastrar um usuรกrio */ } async findByUsername(): Promise<User> { /* * Cรณdigo para buscar um usuรกrio pelo username */ } async update(): Promise<void> { /* * Cรณigo para atualizar um usuรกrio */ } async remove(): Promise<void> { /* * Cรณdigo para remover um usuรกrio */ } }
O processo de chamada deste repositรณrio ocorre por injeรงรฃo de dependรชncia. Crie um mรณdulo de users com o comando:
nest g module users
Este comando gerarรก a pasta users no seguinte formato:
Crie agora o arquivo users.service.ts, com as seguintes configuraรงรตes:
import { UserRepository } from 'src/repositories/UserRepository'; export class UserService { constructor(private readonly usersRepository: UserRepository) {} async create() { /* Block code here... */ } }
Pronto! Aplicamos a primeira regra do SOLID separando nossa camada de repositรณrio da camada de lรณgica do negรณcio.
Caso queira saber mais sobre o Nest e suas implementaรงรตes, รฉ sรณ conferir a documentaรงรฃo neste link.
Gostou desse conteรบdo?
E aรญ, dev! Curtiu esse post? Queremos cada vez mais trazer esse tipo de conteรบdo aqui para vocรชs. Mas alรฉm de encontrar conteรบdos de prรกtica no nosso blog, vocรช tambรฉm encontra muito mais no nosso fรณrum. Se cadastre clicando aqui ou no botรฃo abaixo e fique por dentro de tudo que acontece no mundo do desenvolvimento de software.ย