{"id":22261952,"url":"https://github.com/leoarj/algaworks-isr","last_synced_at":"2026-05-06T22:12:02.648Z","repository":{"id":208126377,"uuid":"720868489","full_name":"leoarj/algaworks-isr","owner":"leoarj","description":"Repository for the basic design of a REST API with Spring, based on AlgaWorks' \"ISR - Ignição Spring REST\" course.","archived":false,"fork":false,"pushed_at":"2024-11-24T00:09:51.000Z","size":210,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-25T13:47:15.778Z","etag":null,"topics":["api-rest","java","spring","springboot"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/leoarj.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-11-19T20:49:36.000Z","updated_at":"2024-11-24T00:09:55.000Z","dependencies_parsed_at":"2023-11-19T22:23:32.595Z","dependency_job_id":"d68a6845-9fb5-4cc1-b8b6-dbe60f68f6db","html_url":"https://github.com/leoarj/algaworks-isr","commit_stats":null,"previous_names":["leoarj/algaworks-isr"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/leoarj/algaworks-isr","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leoarj%2Falgaworks-isr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leoarj%2Falgaworks-isr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leoarj%2Falgaworks-isr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leoarj%2Falgaworks-isr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/leoarj","download_url":"https://codeload.github.com/leoarj/algaworks-isr/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leoarj%2Falgaworks-isr/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32713968,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-06T19:35:05.142Z","status":"ssl_error","status_checked_at":"2026-05-06T19:35:03.996Z","response_time":117,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["api-rest","java","spring","springboot"],"created_at":"2024-12-03T09:15:18.779Z","updated_at":"2026-05-06T22:12:02.620Z","avatar_url":"https://github.com/leoarj.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ISR - Ignição Spring REST (algatransito-api)\n\nUm pequeno projeto de uma API REST para um sistema de autuações de trânsito, com conceitos iniciais e básicos sobre Spring.\n\n![Java](https://img.shields.io/badge/java-%23ED8B00.svg?style=for-the-badge\u0026logo=openjdk\u0026logoColor=white)\n![Spring](https://img.shields.io/badge/spring-%236DB33F.svg?style=for-the-badge\u0026logo=spring\u0026logoColor=white)\n![Apache Maven](https://img.shields.io/badge/Apache%20Maven-C71A36?style=for-the-badge\u0026logo=Apache%20Maven\u0026logoColor=white)\n![Hibernate](https://img.shields.io/badge/Hibernate-59666C?style=for-the-badge\u0026logo=Hibernate\u0026logoColor=white)\n![MySQL](https://img.shields.io/badge/mysql-4479A1.svg?style=for-the-badge\u0026logo=mysql\u0026logoColor=white)\n![IntelliJ IDEA](https://img.shields.io/badge/IntelliJIDEA-000000.svg?style=for-the-badge\u0026logo=intellij-idea\u0026logoColor=white)\n\n## Índice\n- [Sobre](#sobre)\n- [Tecnologias e ferramentas utilizadas](#tecnologias-e-ferramentas-utilizadas)\n- [Como executar](#como-executar)\n- [Tópicos explorados](#tópicos-explorados)\n- [Autor](#autor)\n- [Agradecimentos](#agradecimentos)\n- [Licença](#licença)\n\n## Sobre\nO projeto consiste basicamente em definir 3 entidades no banco de dados e 4 recursos na API com seus endpoints executando diferentes ações utilizando a semântica do protocolo HTTP e seus verbos.\n\nEste projeto aborda modelagem de operações CRUD e operações não-CRUD.\n\n### Modelo de domínio (Banco de dados)\nAs 3 entidades são:\n- **proprietario**\n\u003eTabela para o armazenamento de informações de um proprietário.\n- **veiculo**\n\u003eTabela para o armazenamento de informações de um veículo.\n- **autuacao**\n\u003eTabela para o armazenamento de infrações de um determinado veículo.\n\n### Recursos da API\n\n#### `/proprietarios`\n\nRecurso para manutenção de proprietários de veículos no backend.\n\nDocumentação da API: https://documenter.getpostman.com/view/30781350/2s9YXo1f7V\n\n#### `/veiculos`\n\nRecurso para manutenção de veículos no backend e sub-recurso de apreensão.\n\n##### `/veiculos/{veiculoId}/apreensao`\nSub-recurso para manutenção de aprensão relacionada a um veículo no backend.\n\nDocumentação da API: https://documenter.getpostman.com/view/30781350/2s9YXo1f7X\n\n##### `/autuacoes/{veiculoId}/autuacoes`\n\nSub-recurso para manutenção de autuações relacionadas a um veículo no backend.\n\nDocumentação da API: https://documenter.getpostman.com/view/30781350/2s9YXo1f7Y\n\n### Tecnologias e ferramentas utilizadas\n- Plataforma: Java 17 (LTS) - OpenJDK Temurin\n- Spring:\n    - Spring Framework\n        - Jakarta Bean Validation (Hibernate Validators)\n    - Spring Web\n    - Spring Data JPA\n    - Spring Boot DevTools\n- Suporte a métodos padrão: Lombok\n- Versionamento de DB e migrações: Flyway\n- Mapeamento DTO: ModelMapper\n- Build e empacotamento: Maven\n- DB: MySQL Community 8\n- IDE: IntelliJ\n- Testes e doc. de API: Postman\n- Versionamento: Git\n    - Modelo de braching: Git Flow\n\n## Como Executar\n### Localmente\n- Clonar repositório git\n- Construir o projeto:\n```console\n./mvnw clean package\n```\n- Executar:\n```console\njava -jar algatransito-api/target/algatransito-api-0.0.1-SNAPSHOT.jar\n```\n- Acesso:\n```console\nlocalhost:8080\n```\n\n## Tópicos explorados\n\n### API\n*Application Programming Interface.*\n\nAPIs se baseiam no conceito básico de haver:\n\n*Software consumidor -\u003e **API** \u003c- Software Provedor*\n\n*Softwares **consumidores** que se comunicam com um contrato padronizado e de outro lado há um ou vários sistemas **provedores** da API que respondem pelo contrato padronizado.*\n\n### WebServices vs APIs\n\n**API** = É um termpo bem amplo, onde não temos apenas o conceito do WEB-APIs mas APIs a nível de sistema operacional (OS), SDKs, frameworks.\n\nNo caso de uma API WEB, também pode ser considerada um **WebService**, já que expôe sua **inteface** pela WEB.\n\n### REST = *Representational State Transfer*\n\nEm resumo é uma especificação que define a forma de comunicação entre sistemas na WEB.\n\nREST possui **Constraints**, que são as restrições, regras, melhores práticas.\n\nREST API = Uma WEB API que segue as regras:\n\n- Separação entre cliente e servidor.\n- Escalabilidade.\n- Independência de linguagem.\n- Mercado (integração entre informações)\n\n#### Constraints\n- Cliente-servidor\n\u003eConsumidor (client) e servidor (API), podem evoluir separadamente, sem dependência.\n\n- Stateless\n\u003eSem estado, não deve possuir estado.\n\n- Cache\n\u003eRespostas pode ser cacheadas.\n\n- Interface uniforme\n\u003e(Operações bem definidas) URIs bem definidas.\n\n- Sistema em camadas\n\u003ePossibilidade de existirem outros sistema no meio de forma transparente (cliente não deve necessariamente saber disso).\n\n- Código sob demanda\n\u003eRetornar código que pode ser executado no client (pouco utilizado).\n\n## Protocolo HTTP\nO modelo arquitetural REST independe de tecnologia.\nMas para ser colocado em prática necessita de um protocolo, e nesse caso HTTP é o mais comum.\n\n### HTTP:\nRequisição-Resposta\n\n- Requisição\n    - Método (Vebo) = Ação a ser executada.\n    - URI = /recurso.\n    - HTTP/Versão.\n    - Cabeçalhos = Informações sobre a requisição.\n    - Corpo/PayLoad = Depende do método.\n\n- Resposta\n    - HTTP/Versão.\n    - Status.\n    - Cabeçalhos.\n    - Corpo.\n\n#### Classes Códigos de Status HTTP\n- 1xx - Informacional\n- 2xx - Sucesso\n- 3xx - Redirecionamento\n- 4xx - Erros do cliente\n- 5xx - Erros do servidor\n\n#### Content negotiation\nÉ o meio de um client e um server negociarem o formato de representação dos recursos por meio de um header (cabeçalho) na requisição.\n\nPodem haver vários tipo de representação para um único recurso (JSON, XML etc).\n\nExemplo:\n```console\nAccept application/json\n```\n\nSegue o padrão dos headers:\n- Headers\n    - Key\n    - Value\n\n## Recursos REST\nUm recurso é qualquer \"coisa\" exposta via uma API REST.\n\nEntende-se que um recurso não representa necessariamente uma entidade de banco de dados exposta pelo backend, mas um ou mais agrupamento de recursos que interagem por meio de diferentes representações de dados reais, muitas vezes não expondo sua real estrutura para os consumidores de API.\n\n### Tipos de recursos\n- Singleton resource\n\u003eRecurso único, geralmente possui um identificador pelo qual pode ser buscado.\n\n- Collection resource\n\u003eColeção de recursos, que podem ser obtidos ou não mediante um identificador informado.\n\n#### Modelo de Representação\nRepresenta o estado do recurso (corpo JSON), não é o recurso (é a transformação do resultado, poderia ser JSON ou XML entre outros formatos).\n\n### Identificando recursos\n#### URI Uniform Resource Identifier\nÉ um endereço (conjunto de caracteres) para identificar recursos de forma não ambígua.\n\n#### URI vs URL\n\n- URL = Um tipo de URI.\n\u003eNão apenas o identificador, mas a localização (como ao chegar), mecanismo para acessar.\n\nExemplo:\n```console\n/listarProdutos = URI\nhttps://...../listarProdutos = URL\n```\n#### Boas práticas de nomeação:\n- Sempre um substantivo (Coisas possuem propriedades, verbos não).\n\nExemplo:\n```console\n/produtos\n```\n\nExemplo (singular, fora da convenção):\n```console\n/produto/{codigo} -\u003e recurso único\nhttps://...../produto/331\n```\n\n- Consenso = sempre no plural.\n\nExemplo:\n```console\n/produtos/331\n```\n\n### Métodos e códigos de status HTTP no contexto de recursos\nMétodos/vebos = Ditam a semântica da operação (tipo da operação).\n\n- GET = Obter representação de recurso.\n- POST = Criar novo recurso.\n- PUT = Autualizar/colocar recurso.\n- DELETE = Destruir recurso.\n\n\u003eVerbos indempotentes (GET, PUT, DELETE).\nUma operação indempontente se refere à uma ação que executadas inúmeras vezes sempre manterá o estado no servidor).\nO código de status retornado pode variar, mas o resultado da operação desde a primeira e seguidas requisições permanece o mesmo.\n\n#### Boas práticas\n\n##### Implementando endpoint de criação de recurso\nUtiliza-se POST, ou seja, quando deixa a cargo da API como vai ser a URI do recurso e geração do identificador único.\n\nCódigo de status HTTP (sucesso) = 201 - CREATED.\n\n##### Implementando endpoint de atualização de recurso\nUtiliza-se PUT, ou seja, quando já se sabe a URI do recurso e para modificar informações em recurso existente.\n\nCódigo de status HTTP (sucesso) = 200 - OK.\n\n##### Implementando endpoint de exclusão de recurso\nUtiliza-se DELETE para destruir um recurso, passando sua identificação a partir de uma URI.\n\nCódigo de status HTTP (sucesso) = 204 - NO CONTENT (Operações executadas com sucesso mas que não retornam um conteúdo, que é o caso do DELETE).\n\n## Spring REST\nTermo para dizer que tem uma REST API desenvolvida com Spring.\n\nSpring = Ecossistema de tecnologias.\n\nO objetivo é focar nas regras de negócio, e não se preocupar demasiadamente com infra-estrutura.\n\n\u003e*Não que isso não seja importante, pelo contrário, é ideal conhecer as tecnologias que o Spring trabalha por \"baixo\" das abstrações, mas uma vez tendo esse entendimento, é muito válido prosseguir utilizando uma tecnologia sólida com abstrações que facilitam o uso e principalmente não \"reinventar a roda\", além de ganhar velocidade e melhor entrega de valor para desenvolvedores e usuários finais de sistemas.*\n\nSpring Framework = base/core do projeto Spring.\n\nSpring possui diversos projetos e subprojetos.\n\nUm deles que é utilizado no projeto é o **Spring Boot**, que é focado na autoconfiguração e facilidade de se iniciar um projeto com suas dependências necessárias.\n\nSpring Boot segue uma configuração opinativa (segue uma convenção) e por padrão incorpora um servlet container (Tomcat).\n\n## Flyway\nÉ um projeto que permite o gerenciamento dos objetos do banco de dados, como o versionamento e manutenção de migrações (Migrations), controlando a execução de scripts.\n\n## Criando migração\n- resources\n    - db.migration\n        - nome arquivo: V00X__descricao-migracao.sql\n\nErro de checksum: Deletar linha de histórico.\nObs.: Somente durante o desenvolvimento.\n\n## JPA - Jakarta Persistence\n\nEspecificação do Java para persistência de dados.\n\nImplementação utilizada no projeto foi o Hibernate.\n\n### Spring Data JPA\nProjeto do ecossistema Spring que cria uma camada de abstração facilitando ainda mais o uso do JPA.\n\nNão é uma boa prática utilizar Jakarta Persistence diretamente em um controlador (visando manutenibilidade).\n\n#### Anotações básicas\n`@Repository`\n\u003eMarca uma classe como um componente de acesso a dados.\n\n## Jarkarta Bean Validation\nEspecificação para validação de objetos.\n\nHibernate Validators = Implementação de referência.\n\n### Validação de entrada de dados\n- Anotar propriedades da classe de modelo e/ou representação com as anotações do Jakarta Bean Validation.\n- Adicionar `@Valid` no argumento do endpoint no controlador, para dizer que o objeto precisa ser validado.\n\n## Implementando Domain Services\nDomain Services encapsulam Regras de negócio.\n\nRegras de negócio que envolvem coisas mais simples e que somente se referem à entidade (regras específicas para deixar o modelo rico), então podem ser implementadas na própria entidade.\n\nQuando envolve processos mais complexos e mais classes,\nentão é criada uma classe de serviço.\n\n### Anotações básicas\n`@Service`\n\u003eAnota a classe como um componente, com semântica de que é um serviço.\n\n## Captura de erros do controlador com `@ExceptionHandler`\nMétodo para capturar exceções específicas e com isso poder retornar código de status apropriado juntamente com mensagem reduzida de erro.\n\n### Boas práticas\n`@RestControllerAdvice`\n\u003eAnota uma classe como um componente do Spring para tratamento centralizado de exceções.\n\n### Objetivo\n- Tratar exceções globais, independente do controller que lançou.\n- Evitar duplicação de código para tratamento de exceções.\n\n## RFC 7807 (Problem Details for HTTP APIs)\nEspecificação que padroniza o retorno de descrição de erros para APIs que utilizam HTTP.\n\nO que foi aplicado neste projeto em relação a essa RFC:\n- Customização das informações do ProblemDetail.\n- Campos customizados.\n- Mensagens de validação customizadas.\n- Tratamento de exceções customizadas de forma global.\n\nMais informações: https://www.rfc-editor.org/rfc/rfc7807\n\n## ISO 8601 (Boas práticas com Data e Hora)\nA ISO 8601 padroniza os formatos de data e hora mundialmente, estabelecento um padrão uniforme de representação de objetos temporias.\n\nÉ considerada uma boa prática retornar as datas com offset (Deslocamento de tempo em relação ao UTC), para quem for consumir a API saber o deslocamento de tempo e poder processar corretamente o que for necessário em sua hora local.\n\n- Exemplos válidos\n    - 2023-11-06T21:10:00-03:00\n    - 2023-11-07T00:10:00-00:00\n    - 2023-11-07T00:10:00Z\n\nClasse utilizada na implementação: `java.time.OffsetDateTime`.\n\nMais informações: https://www.iso.org/iso-8601-date-and-time-format.html\n\n## Resource Representation Model\nÉ uma boa prática separar o Domain Model do Representation model.\n\nExistem vários motivos, como:\n- Não expor todas as propriedades do modelo.\n- Evitar quebra da API caso alguma coisa seja alterada no modelo.\n- Criar uma representação mais simples do recurso e não ter que alterar o modelo.\n- Criar uma representação com agrupamento de propriedades de um ou mais recursos.\n- Separar a estrutura do modelo de sua representação em si, que às vezes pode ser exatamente igual ou outras vezes ser diferente.\n\nPara isso, é utilizado o padrão **DTO** *(Data Transfer Object)*.\n\n## ModelMapper\nBiblioteca para automatizar o mapeamento do domain model para o representation model.\n\n## Assembler\nClasses para encapsular o uso do model mapper e deixar o controller livre dessa dependência,\nalém de reaproveitamento de código de conversão dos objetos.\n\n## Composição de objetos no Representation Model\nÉ possível criar uma representação resumida de um recurso para ser usada em outra representação de outro recurso.\n\nExemplo (request-body para inclusão de Veículo):\n```json\n{\n    \"proprietario\": {\n        \"id\": 1\n    },\n    \"marca\": \"Volkswagen\",\n    \"modelo\": \"VOYAGE\",\n    \"placa\": \"PPP0000\"\n}\n```\n\u003e Onde o objeto `proprietario` é uma representação resumida do proprietário somente com o ID (necessário apenas para criação do recurso de véiculo e vinculação com o proprietário).\n\n## Modelo de representação de entrada de dados\nSão modelos personalizados referentes aos recursos, onde se determina apenas as propriedades necessárias para inclusão/alteração de um recurso.\n\nPor via de regra, esses modelos repetem as validações das entidades (preferível).\n\nEssas validações podem ser removidadas das entidades, mas deve-se ter certeza de que o consumo do sistema será exclusivamente pela interface da API WEB(endpoints) definidos.\n\nÉ considerada uma boa prática já que se garante expor apenas a estrutura necessária e ajuda a remover a necessidade de criar algumas validações adicionais caso estivesse utilizando diretamente a entidade.\n\n## Modelando sub-recursos\nRealiza-se a modelagem de um recurso como sub-recurso quando o mesmo possui forte relacionamento com outro e que só existe enquanto o outro recurso existir.\n\nExemplo:\n```console\nrecurso/1/subrecurso\n```\n\nNo caso o recurso de **Autuacões** foi modelado como um sub-recurso de **Veículo**, já que uma autação só pode existir **se um veículo exitir**.\n\nNo caso o recurso de **Apreensão** foi modelado como um sub-recurso de **Veículo**, já que a apreensão aplica modificações diretas no recurso de *Veículo*.\n\nDispensa também ter que passar o **id** do recurso principal no corpo da requisição.\n\n## Endpoints não-CRUD\n\nDeve-se procurar modelar conceitos *abstratos* de negócio como recursos na API.\n\nUm exemplo foi o recurso de **Apreensão**, em que:\n- Chamada PUT em `/veiculos/{veiculoId}/apreensao` torna o status de um veículo como **APREENDIDO** e registra a **data de apreensão**.\n- Chamada DELETE em `/veiculos/{veiculoId}/apreensao` torna o status de um veículo como **REGULAR** e remove a **data de apreensão**.\n\nEm relação ao sub-recurso de `/apreensao`, ele foi nomeado no singular porque representa uma ação única para o recurso de `/veiculos`, porém, apesar de ser uma ação, não foi nomeada como `/apreender` para não perder a semântica de que é um recurso e que possui propriedades, por ser um substativo.\n\nObs.: Sugestão de retorno quando veículo já estiver ou não apreendido = 404 - CONFLICT.\n\n____\n\n## Considerações finais\nEste é um projeto básico e introdutório à construção de APIs REST com Spring.\n\nNão foram implementados recursos de segurança entre outras funcionalidades devido didática do projeto.\n\n### Melhorias futuras pretendidas:\n- Persistência com Postgres.\n- Geração de imagem docker.\n\n## Autor\nLeandro Araújo, desenvolvedor Java, com foco em backend.\u003cbr\u003e\nBusco me aperfeiçoar por meio de cursos e projetos como este, a fim de crescer profissionalmente e humanamente por meio da colaboração.\u003cbr\u003e\u003cbr\u003e\nCaso se sinta à vontade, pode entrar em contato:\n- https://www.linkedin.com/in/leandroaraujoti/\n\n## Agradecimentos\n- https://www.algaworks.com/\n- https://blog.algaworks.com/\n\n## Licença\nEste projeto é licenciado sob a [GNU General Public License v3.0](https://www.gnu.org/licenses/gpl-3.0.html).\n\nPara mais detalhes, consulte o arquivo [LICENSE](./LICENSE).\n\n[Voltar ao início](#isr---ignição-spring-rest-algatransito-api)\n____\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleoarj%2Falgaworks-isr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fleoarj%2Falgaworks-isr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleoarj%2Falgaworks-isr/lists"}