{"id":21685748,"url":"https://github.com/aron-alvarenga/blog-api-java-spring-boot","last_synced_at":"2026-04-14T15:31:43.395Z","repository":{"id":168020263,"uuid":"582064375","full_name":"aron-alvarenga/Blog-API-Java-Spring-Boot","owner":"aron-alvarenga","description":"Blog API em Java Spring Boot com banco de dados MySQL ","archived":false,"fork":false,"pushed_at":"2022-12-25T14:25:51.000Z","size":61,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-13T14:47:34.983Z","etag":null,"topics":["blog-api","java","mysql","spring-boot"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aron-alvarenga.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2022-12-25T14:20:29.000Z","updated_at":"2022-12-25T14:30:36.000Z","dependencies_parsed_at":null,"dependency_job_id":"c7bb2852-3104-4855-85a5-79b9bf272556","html_url":"https://github.com/aron-alvarenga/Blog-API-Java-Spring-Boot","commit_stats":null,"previous_names":["aron-alvarenga/blog-api-java-spring-boot"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/aron-alvarenga/Blog-API-Java-Spring-Boot","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aron-alvarenga%2FBlog-API-Java-Spring-Boot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aron-alvarenga%2FBlog-API-Java-Spring-Boot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aron-alvarenga%2FBlog-API-Java-Spring-Boot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aron-alvarenga%2FBlog-API-Java-Spring-Boot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aron-alvarenga","download_url":"https://codeload.github.com/aron-alvarenga/Blog-API-Java-Spring-Boot/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aron-alvarenga%2FBlog-API-Java-Spring-Boot/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31803195,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-14T11:13:53.975Z","status":"ssl_error","status_checked_at":"2026-04-14T11:13:53.299Z","response_time":153,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: 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":["blog-api","java","mysql","spring-boot"],"created_at":"2024-11-25T16:22:49.454Z","updated_at":"2026-04-14T15:31:43.389Z","avatar_url":"https://github.com/aron-alvarenga.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Blog API\n\n\u003e **API REST** - Sistema completo de gerenciamento de artigos de blog desenvolvido com Spring Boot, demonstrando arquitetura em camadas e boas práticas de desenvolvimento.\n\n[![Java](https://img.shields.io/badge/Java-21-orange.svg)](https://www.oracle.com/java/)\n[![Spring Boot](https://img.shields.io/badge/Spring%20Boot-3.2.0-brightgreen.svg)](https://spring.io/projects/spring-boot)\n[![Maven](https://img.shields.io/badge/Maven-3.6+-C71A36.svg)](https://maven.apache.org/)\n[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n\n## Sobre o Projeto\n\nO **Blog API** é uma API REST completa para gerenciamento de artigos de blog, desenvolvida em Java utilizando Spring Boot Framework. O projeto demonstra arquitetura em camadas bem definidas, separação de responsabilidades e implementação de boas práticas de desenvolvimento, incluindo segurança, validação, tratamento de exceções e monitoramento.\n\n### Objetivos\n\n- Demonstrar arquitetura em camadas (Controller → Service → Repository)\n- Implementar API REST completa com CRUD de artigos\n- Aplicar boas práticas (DTOs, validação, tratamento de exceções, segurança)\n- Suportar múltiplos ambientes (desenvolvimento com H2, produção com MySQL)\n- Servir como **portfólio técnico** demonstrando competências em Spring Boot\n\n## Arquitetura\n\n### Conceito: Arquitetura em Camadas\n\nO projeto segue o padrão de **arquitetura em camadas**, onde:\n\n- **Controller**: Recebe requisições HTTP e delega para a camada de serviço\n- **Service**: Contém a lógica de negócio e orquestra as operações\n- **Repository**: Gerencia acesso aos dados através do Spring Data JPA\n- **DTO**: Objetos de transferência de dados para isolamento da camada de domínio\n- **Mapper**: Conversão automática entre DTOs e entidades usando MapStruct\n- **Exception Handler**: Tratamento global de exceções\n\n### Diagrama de Arquitetura em Camadas\n\n```mermaid\nflowchart TB\n    subgraph Client[\"Cliente HTTP\"]\n        REST[REST Client\u003cbr/\u003eInsomnia/Postman]\n    end\n    \n    subgraph App[\"Blog API Application\"]\n        subgraph Controller[\"Controller Layer\"]\n            ArticleController[ArticleController]\n        end\n        \n        subgraph Service[\"Service Layer\"]\n            ArticleService[ArticleService]\n        end\n        \n        subgraph Repository[\"Repository Layer\"]\n            ArticleRepository[ArticleRepository]\n        end\n        \n        subgraph Model[\"Domain Layer\"]\n            Article[Article Entity]\n        end\n        \n        subgraph DTO[\"DTO Layer\"]\n            RequestDto[ArticleRequestDto]\n            ResponseDto[ArticleResponseDto]\n        end\n        \n        subgraph Mapper[\"Mapper Layer\"]\n            ArticleMapper[ArticleMapper\u003cbr/\u003eMapStruct]\n        end\n        \n        subgraph Config[\"Configuration\"]\n            SecurityConfig[SecurityConfig]\n            ExceptionHandler[GlobalExceptionHandler]\n            JpaConfig[JpaConfig]\n        end\n    end\n    \n    subgraph Database[\"Database\"]\n        H2[(H2 Database\u003cbr/\u003eDesenvolvimento)]\n        MySQL[(MySQL\u003cbr/\u003eProdução)]\n    end\n    \n    REST --\u003e|HTTP Request| ArticleController\n    ArticleController --\u003e|Delega| ArticleService\n    ArticleService --\u003e|Usa| ArticleRepository\n    ArticleService --\u003e|Converte| ArticleMapper\n    ArticleMapper --\u003e|Mapeia| RequestDto\n    ArticleMapper --\u003e|Mapeia| ResponseDto\n    ArticleRepository --\u003e|Persiste| Article\n    Article --\u003e|JPA| H2\n    Article --\u003e|JPA| MySQL\n    \n    SecurityConfig -.-\u003e|Protege| ArticleController\n    ExceptionHandler -.-\u003e|Trata| ArticleController\n    \n    style Controller fill:#e1f5ff\n    style Service fill:#fff4e1\n    style Repository fill:#e8f5e9\n    style Model fill:#f3e5f5\n    style DTO fill:#fce4ec\n    style Mapper fill:#fff9c4\n    style Config fill:#e0f2f1\n    style H2 fill:#e3f2fd\n    style MySQL fill:#ffebee\n```\n\n### Fluxo de Requisição\n\n```mermaid\nsequenceDiagram\n    participant Client\n    participant Controller\n    participant Service\n    participant Mapper\n    participant Repository\n    participant Database\n    \n    Client-\u003e\u003eController: HTTP Request (DTO)\n    Controller-\u003e\u003eController: Validação (@Valid)\n    Controller-\u003e\u003eService: Chama método de serviço\n    Service-\u003e\u003eMapper: Converte DTO → Entity\n    Service-\u003e\u003eRepository: Salva/Busca dados\n    Repository-\u003e\u003eDatabase: Query SQL\n    Database--\u003e\u003eRepository: Resultado\n    Repository--\u003e\u003eService: Entity\n    Service-\u003e\u003eMapper: Converte Entity → DTO\n    Service--\u003e\u003eController: Response DTO\n    Controller--\u003e\u003eClient: HTTP Response (JSON)\n    \n    alt Erro ocorre\n        Controller-\u003e\u003eExceptionHandler: Captura exceção\n        ExceptionHandler--\u003e\u003eClient: Error Response\n    end\n```\n\n## Stack Tecnológica\n\n### Core\n- **Java 21** - Linguagem de programação\n- **Spring Boot 3.2.0** - Framework principal\n- **Spring Security** - Autenticação e autorização\n- **Spring Data JPA** - Persistência de dados\n- **Bean Validation** - Validação de dados\n- **Spring Actuator** - Monitoramento e métricas\n\n### Banco de Dados\n- **H2 Database** - Banco em memória para desenvolvimento/testes\n- **MySQL 8.0+** - Banco de dados para produção\n\n### Ferramentas\n- **Maven** - Gerenciamento de dependências e build\n- **Lombok** - Redução de código boilerplate\n- **MapStruct** - Mapeamento automático DTO ↔ Entity\n- **JUnit 5** - Framework de testes\n- **Mockito** - Framework de mocking para testes\n\n### Modos de Execução\n\nO projeto foi projetado para rodar **sem necessidade de infraestrutura complexa**, oferecendo dois modos de execução:\n\n- **Desenvolvimento**: H2 em memória para rodar rapidamente sem configuração\n- **Produção**: MySQL para ambiente de produção com configuração via variáveis de ambiente\n\nEsta abordagem demonstra flexibilidade para diferentes cenários sem complexidade desnecessária.\n\n## Estrutura do Projeto\n\n```\nblog-api/\n├── src/\n│   ├── main/\n│   │   ├── java/com/aronalvarenga/blog/\n│   │   │   ├── config/                 # Configurações da aplicação\n│   │   │   │   ├── JpaConfig.java\n│   │   │   │   ├── SecurityConfig.java\n│   │   │   │   └── GlobalExceptionHandler.java\n│   │   │   ├── controller/             # Controladores REST\n│   │   │   │   └── ArticleController.java\n│   │   │   ├── dto/                    # Data Transfer Objects\n│   │   │   │   ├── ArticleRequestDto.java\n│   │   │   │   └── ArticleResponseDto.java\n│   │   │   ├── exception/              # Exceções personalizadas\n│   │   │   │   └── ResourceNotFoundException.java\n│   │   │   ├── mapper/                 # Mapeadores MapStruct\n│   │   │   │   └── ArticleMapper.java\n│   │   │   ├── model/                  # Entidades JPA\n│   │   │   │   └── Article.java\n│   │   │   ├── repository/             # Repositórios JPA\n│   │   │   │   └── ArticleRepository.java\n│   │   │   ├── service/                # Lógica de negócio\n│   │   │   │   └── ArticleService.java\n│   │   │   └── BlogApiApplication.java # Classe principal\n│   │   └── resources/\n│   │       ├── application.yml         # Configuração base\n│   │       ├── application-dev.yml    # Configuração desenvolvimento\n│   │       └── application-prod.yml   # Configuração produção\n│   └── test/\n│       └── java/com/aronalvarenga/blog/\n├── pom.xml\n└── README.md\n```\n\n## Como Executar\n\n### Pré-requisitos\n\n- **Java 21+**\n- **Maven 3.6+**\n- **MySQL 8.0+** (apenas para produção - opcional)\n\n### ⚠️ IMPORTANTE: Desenvolvimento com H2\n\n**No modo desenvolvimento, a aplicação usa H2 em memória automaticamente.** Você **NÃO precisa** configurar variáveis de ambiente para desenvolvimento. O H2 é configurado automaticamente no arquivo `application-dev.yml`.\n\n**Console H2 disponível em:** `http://localhost:8080/h2-console`\n- **JDBC URL:** `jdbc:h2:mem:blogdb`\n- **Username:** `sa`\n- **Password:** (deixe em branco)\n\n### Executando Localmente\n\n1. **Clone o repositório**\n   ```bash\n   git clone https://github.com/aron-alvarenga/blog-api.git\n   cd blog-api\n   ```\n\n2. **Execute a aplicação em modo desenvolvimento** (usa H2 em memória automaticamente)\n\n   **Windows (PowerShell):**\n   ```powershell\n   # Opção 1: Com aspas (RECOMENDADO)\n   mvn spring-boot:run \"-Dspring-boot.run.profiles=dev\"\n   \n   # Opção 2: Usando variável de ambiente\n   $env:SPRING_PROFILES_ACTIVE=\"dev\"\n   mvn spring-boot:run\n   \n   # Opção 3: Sem especificar profile (usa 'dev' por padrão)\n   mvn spring-boot:run\n   ```\n\n   **Windows (CMD):**\n   ```cmd\n   mvn spring-boot:run -Dspring-boot.run.profiles=dev\n   ```\n\n   **Linux/macOS:**\n   ```bash\n   mvn spring-boot:run -Dspring-boot.run.profiles=dev\n   ```\n\n   **Nota:** No modo desenvolvimento, a aplicação usa H2 em memória automaticamente. Não é necessário configurar MySQL ou variáveis de ambiente.\n\n3. **Acesse a aplicação**\n   - API: `http://localhost:8080`\n   - Actuator Health: `http://localhost:8080/actuator/health`\n   - H2 Console: `http://localhost:8080/h2-console` (apenas em desenvolvimento)\n\n### Executando em Produção (com MySQL)\n\n#### Configuração de Variáveis de Ambiente\n\nPara produção, você precisa configurar as seguintes variáveis de ambiente:\n\n**Windows (PowerShell):**\n```powershell\n# Database Configuration\n$env:DATABASE_URL=\"jdbc:mysql://localhost:3306/blog_db?useTimezone=true\u0026serverTimezone=UTC\u0026createDatabaseIfNotExist=true\"\n$env:DATABASE_USERNAME=\"root\"\n$env:DATABASE_PASSWORD=\"sua_senha_aqui\"\n\n# Server Configuration\n$env:SERVER_PORT=\"8080\"\n\n# Execute a aplicação\nmvn spring-boot:run \"-Dspring-boot.run.profiles=prod\"\n```\n\n**Nota:** No PowerShell, essas variáveis são válidas apenas para a sessão atual. Para torná-las permanentes:\n\n```powershell\n[System.Environment]::SetEnvironmentVariable(\"DATABASE_URL\", \"jdbc:mysql://localhost:3306/blog_db?useTimezone=true\u0026serverTimezone=UTC\", \"User\")\n[System.Environment]::SetEnvironmentVariable(\"DATABASE_USERNAME\", \"root\", \"User\")\n[System.Environment]::SetEnvironmentVariable(\"DATABASE_PASSWORD\", \"sua_senha_aqui\", \"User\")\n```\n\n**Windows (CMD):**\n```cmd\nset DATABASE_URL=jdbc:mysql://localhost:3306/blog_db?useTimezone=true\u0026serverTimezone=UTC\u0026createDatabaseIfNotExist=true\nset DATABASE_USERNAME=root\nset DATABASE_PASSWORD=sua_senha_aqui\nset SERVER_PORT=8080\nmvn spring-boot:run -Dspring-boot.run.profiles=prod\n```\n\n**Linux/macOS:**\n```bash\nexport DATABASE_URL=\"jdbc:mysql://localhost:3306/blog_db?useTimezone=true\u0026serverTimezone=UTC\u0026createDatabaseIfNotExist=true\"\nexport DATABASE_USERNAME=\"root\"\nexport DATABASE_PASSWORD=\"sua_senha_aqui\"\nexport SERVER_PORT=\"8080\"\nmvn spring-boot:run -Dspring-boot.run.profiles=prod\n```\n\n**Para tornar permanentes no Linux/macOS**, adicione ao arquivo `~/.bashrc` ou `~/.zshrc`:\n\n```bash\necho 'export DATABASE_URL=\"jdbc:mysql://localhost:3306/blog_db?useTimezone=true\u0026serverTimezone=UTC\"' \u003e\u003e ~/.bashrc\necho 'export DATABASE_USERNAME=\"root\"' \u003e\u003e ~/.bashrc\necho 'export DATABASE_PASSWORD=\"sua_senha_aqui\"' \u003e\u003e ~/.bashrc\necho 'export SERVER_PORT=\"8080\"' \u003e\u003e ~/.bashrc\nsource ~/.bashrc\n```\n\n#### Configuração do MySQL\n\n1. **Instale o MySQL 8.0+**\n   - Windows: [MySQL Installer](https://dev.mysql.com/downloads/installer/)\n   - Linux: `sudo apt-get install mysql-server` (Ubuntu/Debian)\n   - macOS: `brew install mysql`\n\n2. **Crie o banco de dados**\n   ```sql\n   CREATE DATABASE blog_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;\n   ```\n\n3. **Crie um usuário (opcional)**\n   ```sql\n   CREATE USER 'blog_user'@'localhost' IDENTIFIED BY 'senha_segura';\n   GRANT ALL PRIVILEGES ON blog_db.* TO 'blog_user'@'localhost';\n   FLUSH PRIVILEGES;\n   ```\n\n4. **Verifique a conexão**\n   ```bash\n   mysql -u root -p -e \"SHOW DATABASES;\"\n   ```\n\n### Troubleshooting\n\n#### Problema: Aplicação não inicia em modo produção\n\n**Solução:**\n1. Verifique se as variáveis de ambiente estão configuradas corretamente\n2. Verifique se o MySQL está rodando: `mysql -u root -p`\n3. Verifique se o banco de dados existe: `SHOW DATABASES;`\n4. Verifique as credenciais no arquivo `application-prod.yml`\n\n#### Problema: Erro de conexão com MySQL\n\n**Solução:**\n1. Verifique se o MySQL está rodando\n2. Verifique se a porta 3306 está acessível\n3. Verifique se o usuário tem permissões no banco de dados\n4. Verifique se o timezone está configurado corretamente na URL de conexão\n\n#### Problema: H2 Console não aparece\n\n**Solução:**\n1. Certifique-se de que está usando o profile `dev`\n2. Verifique se `spring.h2.console.enabled=true` no `application-dev.yml`\n3. Acesse `http://localhost:8080/h2-console`\n\n## Endpoints da API\n\n### Endpoints Públicos\n\n| Método | Endpoint | Descrição |\n|--------|----------|-----------|\n| `GET` | `/api/v1/articles/published` | Lista todos os artigos publicados |\n| `GET` | `/api/v1/articles/published/paginated` | Lista artigos publicados com paginação |\n| `GET` | `/api/v1/articles/published/search?title=termo` | Busca artigos publicados por título |\n| `GET` | `/api/v1/articles/{id}` | Busca artigo por ID (se publicado) |\n| `GET` | `/actuator/health` | Health check da aplicação |\n| `GET` | `/h2-console` | Console H2 (apenas em desenvolvimento) |\n\n### Endpoints Protegidos\n\n| Método | Endpoint | Descrição |\n|--------|----------|-----------|\n| `GET` | `/api/v1/articles` | Lista todos os artigos |\n| `GET` | `/api/v1/articles/paginated` | Lista artigos com paginação |\n| `GET` | `/api/v1/articles/search?title=termo` | Busca artigos por título |\n| `GET` | `/api/v1/articles/author/{author}` | Busca artigos por autor |\n| `POST` | `/api/v1/articles` | Cria novo artigo |\n| `PUT` | `/api/v1/articles/{id}` | Atualiza artigo existente |\n| `DELETE` | `/api/v1/articles/{id}` | Exclui artigo |\n| `PATCH` | `/api/v1/articles/{id}/publish` | Publica artigo |\n| `PATCH` | `/api/v1/articles/{id}/unpublish` | Despublica artigo |\n\n## Testes\n\n### Executando Testes\n\n```bash\n# Executar todos os testes\nmvn test\n\n# Executar testes com cobertura (quando configurado)\nmvn test jacoco:report\n```\n\n### Estratégia de Testes\n\n- **Testes Unitários**: Lógica de negócio e validações\n- **Testes de Integração**: Endpoints e persistência\n- **Testes de Segurança**: Endpoints protegidos\n\n## Segurança\n\nA aplicação implementa segurança básica com Spring Security:\n\n- Endpoints públicos para leitura de artigos publicados\n- Endpoints protegidos para operações de escrita\n- Configuração preparada para implementação futura de JWT\n- Tratamento global de exceções\n- Validação de dados com Bean Validation\n\n### Boas Práticas de Segurança\n\n- **NUNCA** commite arquivos `.env` ou com credenciais\n- Use variáveis de ambiente para dados sensíveis\n- Em produção, configure um gerenciador de segredos (AWS Secrets Manager, Azure Key Vault, HashiCorp Vault, etc.)\n- Mantenha as senhas de banco de dados seguras e complexas\n- Use diferentes credenciais para desenvolvimento e produção\n\n### Arquivos Sensíveis\n\nCertifique-se de que os seguintes arquivos estão no `.gitignore`:\n\n```\n.env\n*.env\napplication-local.yml\napplication-secrets.yml\n```\n\n## Monitoramento\n\nA aplicação inclui Spring Actuator para monitoramento:\n\n- **Health checks**: `/actuator/health`\n- **Métricas**: `/actuator/metrics`\n- **Informações**: `/actuator/info`\n\n## Melhorias Implementadas\n\n### Arquitetura\n- Separação clara de responsabilidades (Controller, Service, Repository)\n- Uso de DTOs para transferência de dados\n- Mapeamento automático com MapStruct\n- Tratamento global de exceções\n- Validação de dados com Bean Validation\n\n### Segurança\n- Configuração de segurança básica\n- Endpoints públicos e protegidos\n- Variáveis de ambiente para dados sensíveis\n- .gitignore atualizado para arquivos sensíveis\n\n### Qualidade de Código\n- Uso correto do Lombok\n- Logging estruturado\n- Testes unitários\n- Documentação de código\n- Configuração de profiles (dev/prod)\n\n### Configuração\n- Migração para YAML\n- Profiles de desenvolvimento e produção\n- Configuração de banco de dados otimizada\n- Configuração de logging por ambiente\n\n## Novo Direcionamento\n* Transformar em um CMS completo incluindo:\n    * **Conteúdo**: artigos com rascunho/publicação, slug, SEO (meta title/description), versões.\n    * **Autoria**: usuários + papéis (ADMIN/EDITOR/AUTHOR).\n    * **Mídia**: upload de imagens (mesmo que inicialmente local), capa do post.\n    * **Moderação**: comentários com aprovação, anti-spam simples.\n    * **Observabilidade**: logs, métricas, health checks, tracing opcional.\n    * **Infra/entrega**: Docker Compose + MySQL/Postgres, Flyway, CI.\n\n\n## Contribuindo\n\nEste é um projeto de portfólio pessoal. Contribuições são bem-vindas! Sinta-se à vontade para abrir issues e pull requests.\n\n## Licença\n\nEste projeto está sob a licença MIT. Veja o arquivo [LICENSE](LICENSE) para mais detalhes.\n\n## Autor\n\n**Aron Alvarenga**\n\n- GitHub: [@aron-alvarenga](https://github.com/aron-alvarenga)\n- LinkedIn: [Aron Alvarenga](https://www.linkedin.com/in/aron-alvarenga)\n\n## Agradecimentos\n\n- Spring Framework e comunidade Spring\n- Todos os mantenedores das bibliotecas open-source utilizadas\n\n---\n\n**Nota**: Este projeto demonstra boas práticas de desenvolvimento com Spring Boot, mantendo simplicidade e foco na qualidade do código.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faron-alvarenga%2Fblog-api-java-spring-boot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faron-alvarenga%2Fblog-api-java-spring-boot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faron-alvarenga%2Fblog-api-java-spring-boot/lists"}