Skip to content

GitLab

  • Menu
Projects Groups Snippets
    • Loading...
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in
  • Wiki Wiki
  • Project information
    • Project information
    • Activity
    • Labels
    • Planning hierarchy
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 0
    • Issues 0
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 0
    • Merge requests 0
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Monitor
    • Monitor
    • Incidents
  • Packages & Registries
    • Packages & Registries
    • Package Registry
    • Infrastructure Registry
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • Lucky Draw
  • WikiWiki
  • Wiki
  • Backend

Backend · Changes

Page history
Update Backend authored Mar 17, 2025 by Caroline Lewandowski's avatar Caroline Lewandowski
Hide whitespace changes
Inline Side-by-side
Backend.md
View page @ 8f292c3e
...@@ -38,4 +38,139 @@ Diante disso, os pacotes do projeto estão divididos da forma abaixo: ...@@ -38,4 +38,139 @@ Diante disso, os pacotes do projeto estão divididos da forma abaixo:
* :file_folder: `repository`: Implementa a lógica de acesso ao banco de dados para buscar e persistir dados. * :file_folder: `repository`: Implementa a lógica de acesso ao banco de dados para buscar e persistir dados.
* :file_folder: `service`: Classes que implementam as interfaces em _service\*. * :file_folder: `service`: Classes que implementam as interfaces em _service\*.
* :file_folder: `interfaces`: Implementação da lógica de negócio (interfaces). Se necessário buscar ou salvar dados, delega isso para a camada de _repository\* * :file_folder: `interfaces`: Implementação da lógica de negócio (interfaces). Se necessário buscar ou salvar dados, delega isso para a camada de _repository\*
* :file_folder: `util`: Classes e métodos utilitários (ex.: formatação de datas) * :file_folder: `util`: Classes e métodos utilitários (ex.: formatação de datas)
\ No newline at end of file
## Padrões de código
### Nomenclatura de classes
Classes do projeto devem ser nomeadas em inglês e seguir o padrão **PascalCase**, ou seja, devem iniciar com letra maiúscula e cada palavra ou abreviatura no meio da frase também deve iniciar com letra maiúscula. Por exemplo:
* UserController :heavy_check_mark:
* User_Controller :x:
* Usercontroller :x:
* userController :x:
Além disso, com exceção do pacote model, os nomes das classes devem refletir o pacote onde elas estão localizadas, conforme o exemplo abaixo:
* :file_folder: config: ExemploConfig
* :file_folder: controller: ExemploController
* :file_folder: dt.request: ExemploRequest
* :file_folder: dt.response: ExemploResponse
* :file_folder: exception: ExemploException
* :file_folder: repository: ExemploRepository
* :file_folder: service: ExemploService
* :file_folder: util: ExemploUtil
### Nomenclatura de variáveis
Variáveis devem ser nomeadas em inglês e seguir o padrão **camelCase**, ou seja, devem iniciar com letra minúscula e cada palavra ou abreviatura no meio da frase deve iniciar com letra maiúscula. Por exemplo:
* isAdmin :heavy_check_mark:
* isadmin :x:
* is_Admin :x:
* IsAdmin :x:
A exceção são as variáveis constantes (que devem ser estáticas e finais) e enums, que devem seguir o padrão **SCREAMING_SNAKE_CASE**, onde as palavras no meio da frase são separadas por *underscores* (_) e as letras devem ser todas maiúsculas. Por exemplo: API_BASE_URL
Além disso, para criar um código limpo e fácil de entender e realizar a manutenção depois, sempre nomeie as variáveis de forma que fique claro o seu propósito/o tipo de informação que ela possui. Para isso, seguem algumas dicas:
* Evitar abreviações.
* Para variáveis booleanas, não nomear apenas com substantivos, para deixar claro que é um booleano. Por exemplo, ao invés de "publish", usem "isPublished".
* Criar variáveis fáceis de pronunciar.
* Evitar dar nomes muito parecidos para duas variáveis.
* Não usar números mágicos. Se existir algum número que precisa ser utilizado no código, criar uma variável para este número para deixar claro o que ele significa.
### Nomenclatura de métodos
Variáveis devem ser nomeadas em inglês e seguir o padrão **camelCase**, ou seja, devem iniciar com letra minúscula e cada palavra ou abreviatura no meio da frase deve iniciar com letra maiúscula. Por exemplo:
* findUserByName :heavy_check_mark:
* finduserbyname :x:
* find_User_By_Name :x:
* FindUserByName :x:
Além disso, para facilitar a leitura do código, em uma classe os métodos sempre devem estar organizados na ordem abaixo:
1. Métodos `public`
1. Métodos `protected`
1. Métodos `private`
### Padrões das APIs REST
A API desenvolvida para este projeto deverá seguir o estilo de arquitetura REST, muito utilizado para o desenvolvimento de APIs web, e para isso algumas restrições e boas práticas devem ser seguidos. Neste estilo, as informações gerenciadas pela aplicação e que possuem uma identificação única são chamadas de recursos (pode-se dizer que são mapeamentos conceituais/abstratos às entidades da aplicação), e as URIs da aplicação (*Uniform Resource Identifiers*) devem referenciar estes recursos de forma clara e padronizada.
Abaixo segue um exemplo de uma API fictícia para ilustrar o padrão que deve ser utilizado pela aplicação:
* **GET /v1/books** - buscar lista/coleção de livros
* **GET /v1/books/1** - buscar um livro específico a partir de um identificador único
* **POST /v1/books** - criar/registrar um novo livro
* **PATCH /v1/books/1** - editar um livro específico a partir de um identificador único (atualizações parciais)
* **PUT /v1/books/1** - editar um livro específico a partir de um identificador único (substituindo a representação do recurso pelos novos dados informados)
* **DELETE /v1/books/1** - deletar um livro específico a partir de um identificador único
Os recursos devem ser referenciados como substantivos no plural, e também deve se adicionar o versionamento da API no começo do *path*, conforme exemplos acima. Além disso, caso exista algum recurso que precise ser representado com mais de uma palavra, estas devem ser separadas por hífens, por exemplo: **/v1/loan-contracts**
Para mais informações, sugere-se a leitura [deste link](https://www.alura.com.br/artigos/rest-principios-e-boas-praticas), que traz algumas boas práticas de forma didática.
### Checkstyle
Para estabelecer padrões e regras de codificação no projeto, e verificar de forma fácil se o código escrito está aderente a estas regras ou não, estabeleceu-se no projeto o uso da ferramenta Checkstyle, que realiza uma análise de código estático e aponta os pontos do código implementado onde ocorreram violações dos padrões. Para este projeto, foi habilitada a verificação das convenções de "Sun's Java Style", que podem ser vistas nesta [documentação](https://checkstyle.org/sun_style.html).
As instruções de como executar a análise do Checkstyle no projeto podem ser vistas no [README do repositório de Backend](https://tools.ages.pucrs.br/sem-barreiras/sembarreiras-backend/-/blob/main/README.md#checando-padr%C3%B5es-de-codifica%C3%A7%C3%A3o).
## Tratamento de exceções
No projeto, dentro do pacote `config`, existe a classe `GlobalExceptionHandler`, que foi criada para que as exceções lançadas pela a aplicação durante a execução sejam tratadas e retornadas com um corpo de resposta e status HTTP de resposta apropriados.
Em casos de erro, o corpo da resposta deve sempre seguir um formato padronizado, conforme exemplo abaixo. Este formato é aquele modelado pela classe `ErrorResponse`.
```json
{
"error": "Mensagem da excecao"
}
```
Para garantir que esse padrão seja seguido para as diferentes exceções que possam ocorrer, foi criado um método genérico para tratamento de exceção nesta classe `GlobalExceptionHandler` onde, ao ser lançada uma exceção do tipo `HttpException`, retorna-se uma resposta com a mensagem e o status HTTP que são atributos desta classe.
Ou seja, novas exceções criadas dentro do pacote `exception` devem ser subclasses da classe pai `HttpException`, e devem informar no construtor o status HTTP a ser retornado e a mensagem de erro. Assim, será feito o tratamento descrito acima sem precisar de nenhum código adicional.
Para mais informações, leia [esta documentação do Spring](https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc).
## Validação de parâmetros das requisições
Ao receber uma nova requisição, é importante verificar se os parâmetros necessários vieram preenchidos de forma completa e com valores que façam sentido. Uma forma na qual se pode fazer isso é utilizando a API de validação de Beans do Java.
A API disponibiliza várias anotações que podem ser utilizadas para validar diferentes cenários, a exemplo de:
* @NotNull: verifica se a variável/atributo é nulo.
* @NotBlank: verifica se a variável/atributo String é nulo ou é uma String vazia.
* @Min: verifica se a variável/atributo tem valor igual ou maior que o valor mínimo informado.
* @Max: verifica se a variável/atributo tem valor igual ou menor que o valor máximo informado.
Supondo um cenário onde existe um *endpoint* de uma aplicação de biblioteca, para registro de novos livros, onde se recebe um corpo de requisição JSON, para realizar a validação precisariam ser feitos os ajustes abaixo:
1. Na classe DTO que modela os dados do corpo da requisição, adicionar as anotações nos atributos que se deseja validar.
```java
public class BookRequest {
@NotBlank(message = "Titulo precisa ser informado.")
private String title;
@NotBlank(message = "Autor precisa ser informado.")
private String author;
@Min(value = 1, message = "Ano de lancamento precisa ser valido.")
private Integer releaseYear;
}
```
1. Adicionar a anotação @Valid no método do controller onde se recebe o corpo da requisição. `java @PostMapping public BookResponse createBook(@Valid @RequestBody BookRequest bookRequest) { ... } `Para mais informações, leia [esta página](https://www.baeldung.com/java-validation).
## Documentação do Swagger
A ferramenta Swagger (OpenAPI) já foi configurada na aplicação, para documentação da API e para permitir testar requisições HTTP via interface gráfica. Diante disso, novos *controllers* REST que forem criados já vão ser exibidos na [url do Swagger](http://localhost:8080/swagger-ui/index.html) sem precisar de nenhuma configuração adicional.
No entanto, para garantir que a API esteja bem documentada, sugere-se utilizar as anotações da API do Swagger para descrever melhor quais são os propósitos de cada *endpoint* e quais são os significados de cada parâmetro de requisição e código de resposta. Seguem alguns exemplos de anotação abaixo:
* @Operation: usada para descrever uma operação no Swagger (adicionar resumo, tags, etc)
* @Parameter: usada para descrever um parâmetro de uma requisição HTTP (propósito do parâmetro, exemplo de valor, etc)
Para mais informações, leia [esta página](https://springdoc.org/v1/).
\ No newline at end of file
Clone repository
  • Arquitetura
  • Backend
  • Banco de dados
  • Codigo
  • Configuracao
  • Design & Mockups
  • Escopo e Cronograma
  • Frontend
  • Infraestrutura
  • Processo
  • Qualidade
  • Home