18 KiB
📰 BLOG-API — Microserviço de Blog/Notícias
Este é o microserviço responsável pelo gerenciamento de posts, categorias, notícias publicadas, conteúdos em destaque e listagens públicas filtradas dentro de um ecossistema baseado em APIs. O serviço permite cadastrar, consultar, atualizar e remover conteúdos de blog/notícias, além de disponibilizar endpoints públicos para consumo por frontend, gateway ou outros microsserviços.
👥 Integrantes do Grupo
- João Carlos Campos
- Lucas Higinio
📝 Descrição do Serviço
O BLOG-API atua como o serviço central de publicação de conteúdos informativos em uma arquitetura de microsserviços. Ele resolve o problema de organização e distribuição de notícias, permitindo que administradores cadastrem categorias e posts, enquanto usuários e outros serviços consomem apenas os conteúdos públicos publicados.
A API foi desenvolvida em Laravel 12, utilizando uma estrutura organizada com Models, Migrations, Controllers, Form Requests, API Resources e rotas versionadas em /api/v1. O projeto está preparado para evoluir com autenticação JWT nas rotas administrativas, mantendo separadas as operações públicas de leitura e as operações administrativas de escrita.
⚙️ Responsabilidades do Microsserviço
- Gerenciamento de Categorias: cadastrar, listar, consultar, atualizar e excluir categorias de notícias.
- Gerenciamento de Posts: cadastrar, listar, consultar, atualizar e excluir posts do blog/notícias.
- Geração de Slugs: criar slugs automaticamente a partir do nome da categoria ou título do post.
- Controle de Publicação: permitir que posts sejam definidos como
draftoupublished. - Posts em Destaque: permitir marcação de conteúdos especiais por meio do campo
is_featured. - Listagem Pública: disponibilizar posts e categorias para consumo externo.
- Filtros e Paginação: permitir busca por título, categoria, destaque, status e paginação.
- Validação de Dados: validar entradas por meio de Form Requests.
- Padronização de Respostas: retornar dados em JSON utilizando API Resources.
- Health Checks: fornecer rotas para verificar a saúde da API e da conexão com o banco.
🛠️ Tecnologias Utilizadas
| Tecnologia | Uso no Projeto |
|---|---|
| PHP 8.2+ | Linguagem principal utilizada pela aplicação. |
| Laravel 12 | Framework utilizado para construção da API REST. |
| Composer | Gerenciador de dependências PHP. |
| MySQL/MariaDB | Banco de dados relacional utilizado pelo microserviço. |
| XAMPP | Ambiente local usado para executar Apache, PHP e MySQL/MariaDB no Windows. |
| PowerShell | Terminal utilizado para execução dos comandos e testes locais. |
| Git | Controle de versão do código-fonte. |
| GitHub/Git remoto | Hospedagem do repositório e entrega do projeto. |
⚙️ Requisitos Necessários
Para rodar este microserviço localmente, é necessário ter instalado:
- PHP 8.2 ou superior.
- Composer 2.x ou superior.
- MySQL ou MariaDB, podendo ser pelo XAMPP.
- Git para clonar e versionar o projeto.
- PowerShell, Prompt de Comando, Git Bash ou terminal equivalente.
| Requisito | Versão Recomendada |
|---|---|
| PHP | 8.2+ |
| Laravel | 12.x |
| Composer | 2.x+ |
| Banco de dados | MySQL 8.x ou MariaDB compatível |
| Servidor local | XAMPP ou equivalente |
📦 Ambiente de Execução
Este projeto foi configurado para execução sem Docker, utilizando ambiente local com XAMPP no Windows. Portanto, os arquivos Dockerfile e docker-compose.yml não são obrigatórios nesta entrega.
A opção escolhida para esta entrega foi a execução local sem Docker. Caso o projeto seja migrado futuramente para containers, será necessário criar o
Dockerfile, odocker-compose.ymle atualizar esta documentação com portas, serviços, volumes e variáveis de ambiente.
🚀 Passo a Passo de Instalação e Execução
1. Clonar o Repositório
git clone https://github.com/JCUNME12/BLOG-API.git
cd BLOG-API
Caso esteja usando o repositório institucional, utilize:
git clone https://git.juancjc.com.br/Joao_Carlos_Campos/blog-api.git
cd blog-api
2. Instalar as Dependências
composer install
3. Criar o Arquivo .env
No Windows PowerShell, execute:
copy .env.example .env
Em Linux, macOS ou Git Bash, execute:
cp .env.example .env
4. Gerar a Chave da Aplicação
php artisan key:generate
5. Criar o Banco de Dados
No MySQL/MariaDB, crie um banco chamado blog_api:
CREATE DATABASE blog_api;
6. Executar as Migrations
php artisan migrate
7. Iniciar o Servidor Local
php artisan serve
A aplicação ficará disponível em:
http://127.0.0.1:8000
🔐 Configuração do .env
O arquivo .env.example deve ficar versionado no repositório. Já o arquivo .env real deve permanecer apenas na máquina local, pois contém configurações específicas do ambiente.
APP_NAME="Blog API"
APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_URL=http://127.0.0.1:8000
APP_LOCALE=pt_BR
APP_FALLBACK_LOCALE=pt_BR
APP_FAKER_LOCALE=pt_BR
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=blog_api
DB_USERNAME=root
DB_PASSWORD=
CACHE_STORE=file
SESSION_DRIVER=file
QUEUE_CONNECTION=sync
LOG_CHANNEL=stack
LOG_LEVEL=debug
Após alterar configurações de ambiente, limpe o cache do Laravel:
php artisan config:clear
php artisan route:clear
🧭 Observação Importante sobre Laravel 12
Em projetos Laravel 12, o arquivo routes/api.php precisa estar registrado no bootstrap/app.php. O bloco withRouting deve conter a entrada api:
->withRouting(
web: __DIR__.'/../routes/web.php',
api: __DIR__.'/../routes/api.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
)
Sem essa configuração, as rotas /api/v1/... podem retornar 404 Not Found, mesmo que estejam corretamente declaradas no arquivo routes/api.php.
🧪 Como Testar o Projeto
Para testar as rotas da API, podem ser usadas ferramentas como Postman, Insomnia ou o próprio terminal com Invoke-RestMethod no PowerShell.
Teste de Saúde da API
Invoke-RestMethod -Uri "http://127.0.0.1:8000/api/v1/health" -Method Get
Teste de Conexão com o Banco
Invoke-RestMethod -Uri "http://127.0.0.1:8000/api/v1/health-check-db" -Method Get
Cabeçalhos Recomendados para POST, PUT e PATCH
Accept: application/json
Content-Type: application/json
🔒 Rotas da API
Todas as rotas principais usam o prefixo /api/v1. As rotas públicas são voltadas para leitura, enquanto as rotas administrativas realizam operações de criação, atualização e exclusão.
| Método | Endpoint | Tipo | Descrição |
|---|---|---|---|
GET |
/api/v1/health |
Público | Verifica se a API está online. |
GET |
/api/v1/health-check-db |
Público | Verifica a conexão com o banco de dados. |
GET |
/api/v1/public/posts |
Público | Lista posts publicados com filtros e paginação. |
GET |
/api/v1/public/posts/{slug} |
Público | Busca um post publicado pelo slug. |
GET |
/api/v1/public/categories |
Público | Lista categorias disponíveis. |
GET |
/api/v1/public/categories/{slug} |
Público | Busca uma categoria pelo slug. |
GET |
/api/v1/admin/posts |
Administrativo | Lista posts no contexto administrativo. |
POST |
/api/v1/admin/posts |
Administrativo | Cria um novo post. |
GET |
/api/v1/admin/posts/{id} |
Administrativo | Busca um post por ID. |
PUT/PATCH |
/api/v1/admin/posts/{id} |
Administrativo | Atualiza um post existente. |
DELETE |
/api/v1/admin/posts/{id} |
Administrativo | Remove um post. |
GET |
/api/v1/admin/categories |
Administrativo | Lista categorias no contexto administrativo. |
POST |
/api/v1/admin/categories |
Administrativo | Cria uma nova categoria. |
GET |
/api/v1/admin/categories/{id} |
Administrativo | Busca uma categoria por ID. |
PUT/PATCH |
/api/v1/admin/categories/{id} |
Administrativo | Atualiza uma categoria existente. |
DELETE |
/api/v1/admin/categories/{id} |
Administrativo | Remove uma categoria sem posts vinculados. |
🔎 Filtros Disponíveis na Listagem de Posts
| Parâmetro | Tipo | Exemplo | Finalidade |
|---|---|---|---|
search |
string | /api/v1/public/posts?search=Laravel |
Busca posts pelo título. |
category_id |
integer | /api/v1/public/posts?category_id=1 |
Filtra posts por ID da categoria. |
category_slug |
string | /api/v1/public/posts?category_slug=tecnologia |
Filtra posts pelo slug da categoria. |
is_featured |
boolean | /api/v1/public/posts?is_featured=true |
Filtra posts em destaque. |
status |
string | /api/v1/public/posts?status=published |
Filtra por draft ou published. |
per_page |
integer | /api/v1/public/posts?per_page=15 |
Define a quantidade de itens por página. |
📤 Exemplos de Requisição e Resposta em JSON
Criar Categoria
Endpoint: POST /api/v1/admin/categories
Corpo da requisição:
{
"name": "Tecnologia",
"description": "Noticias sobre tecnologia, inovacao e software."
}
Retorno esperado:
{
"data": {
"id": 1,
"name": "Tecnologia",
"slug": "tecnologia",
"description": "Noticias sobre tecnologia, inovacao e software.",
"posts_count": 0,
"created_at": "2026-05-28T16:17:19.000000Z",
"updated_at": "2026-05-28T16:17:19.000000Z"
}
}
Criar Post
Endpoint: POST /api/v1/admin/posts
Corpo da requisição:
{
"title": "Laravel 12 em Microsservicos",
"content": "Conteudo completo da noticia sobre Laravel 12 em uma arquitetura de microsservicos.",
"excerpt": "Resumo da noticia sobre Laravel 12.",
"category_id": 1,
"featured_image": "https://cdn.example.com/images/laravel.jpg",
"is_featured": true,
"status": "published",
"published_at": "2026-05-28 10:00:00"
}
Retorno esperado:
{
"data": {
"id": 1,
"title": "Laravel 12 em Microsservicos",
"slug": "laravel-12-em-microsservicos",
"content": "Conteudo completo da noticia sobre Laravel 12 em uma arquitetura de microsservicos.",
"excerpt": "Resumo da noticia sobre Laravel 12.",
"featured_image": "https://cdn.example.com/images/laravel.jpg",
"is_featured": true,
"status": "published",
"published_at": "2026-05-28T10:00:00.000000Z",
"category": {
"id": 1,
"name": "Tecnologia",
"slug": "tecnologia",
"description": "Noticias sobre tecnologia, inovacao e software."
}
}
}
Listar Posts Publicados
Endpoint: GET /api/v1/public/posts
Retorno esperado:
{
"data": [
{
"id": 1,
"title": "Laravel 12 em Microsservicos",
"slug": "laravel-12-em-microsservicos",
"excerpt": "Resumo da noticia sobre Laravel 12.",
"is_featured": true,
"status": "published",
"published_at": "2026-05-28T10:00:00.000000Z",
"category": {
"id": 1,
"name": "Tecnologia",
"slug": "tecnologia"
}
}
],
"links": {
"first": "http://127.0.0.1:8000/api/v1/public/posts?page=1",
"last": "http://127.0.0.1:8000/api/v1/public/posts?page=1",
"prev": null,
"next": null
},
"meta": {
"current_page": 1,
"per_page": 15,
"total": 1
}
}
Excluir Post
Endpoint: DELETE /api/v1/admin/posts/1
Retorno esperado:
{
"message": "Post deleted successfully."
}
📥 Dados Recebidos e Retornados
O serviço recebe dados relacionados às entidades Categoria e Post. As respostas são retornadas em JSON e seguem uma estrutura padronizada por meio de API Resources.
| Entidade | Dados Recebidos |
|---|---|
| Categoria | name, slug opcional, description |
| Post | title, slug opcional, content, excerpt, category_id, featured_image, is_featured, status, published_at |
| Resposta | Dados Retornados |
|---|---|
| Categoria | id, name, slug, description, posts_count, created_at, updated_at |
| Post | id, title, slug, content, excerpt, featured_image, is_featured, status, published_at, category, created_at, updated_at |
| Paginação | data, links, meta |
🔗 Integrações com Outros Microsserviços
Este serviço trabalha de forma desacoplada, mas foi projetado para integrar um ecossistema maior. Nesta versão, a integração real implementada é com seu próprio banco de dados. As demais integrações estão documentadas como evolução futura.
| Serviço | Tipo de Integração | Situação | Descrição |
|---|---|---|---|
| Banco MySQL/MariaDB | Consumo direto | Implementado | Armazena posts, categorias e metadados. |
| Auth Service | Consumo futuro | Preparado | Poderá validar tokens JWT para proteger rotas administrativas. |
| API Gateway | Consumidor da API | Previsto | Poderá centralizar chamadas para o BLOG-API. |
| Frontend Web/Mobile | Consumidor da API | Previsto | Poderá exibir posts, categorias, destaques e buscas. |
| Notification Service | Consumidor futuro | Previsto | Poderá notificar usuários quando novos posts forem publicados. |
| Search Service | Consumidor futuro | Previsto | Poderá indexar posts publicados para busca global. |
| Media/Storage Service | Consumo futuro | Previsto | Poderá armazenar imagens usadas no campo featured_image. |
🔄 Fluxo Principal do Serviço
O fluxo principal começa quando um administrador cria uma categoria e cadastra um post vinculado a ela. O BLOG-API valida os dados recebidos, gera o slug automaticamente, salva o conteúdo no banco e disponibiliza o post nas rotas públicas quando o status está como published.
Administrador cadastra categoria
↓
Administrador publica notícia
↓
BLOG-API valida, gera slug e salva no banco
↓
Frontend/Gateway consulta /api/v1/public/posts
↓
Usuário visualiza notícia publicada
↓
Serviços de busca/notificação podem consumir o conteúdo publicado
| Etapa | Descrição |
|---|---|
| 1 | O administrador cria uma categoria, como Tecnologia. |
| 2 | O administrador cria um post vinculado à categoria. |
| 3 | O serviço valida os dados usando Form Requests. |
| 4 | O sistema gera automaticamente os slugs. |
| 5 | O post é salvo como draft ou published. |
| 6 | Se estiver publicado, o post aparece nas rotas públicas. |
| 7 | Frontend, gateway ou outros serviços consomem a listagem. |
⚠️ Possíveis Erros e Retornos Esperados
Caso algo saia do fluxo ideal, a API retorna códigos HTTP e mensagens adequadas para facilitar o tratamento pelo cliente.
| Situação | Código HTTP | Exemplo de Retorno |
|---|---|---|
| Dados inválidos | 422 |
Campos obrigatórios ausentes ou em formato inválido. |
| Post inexistente | 404 |
Registro de post não encontrado. |
| Categoria inexistente | 404 |
Registro de categoria não encontrado. |
| Categoria com posts vinculados | 409 |
Exclusão bloqueada por conflito de integridade. |
| Erro interno | 500 |
Erro inesperado no servidor. |
| Banco indisponível | 503 |
Falha no health check do banco de dados. |
Exemplo de Erro de Validação
{
"message": "The title field is required.",
"errors": {
"title": [
"The title field is required."
]
}
}
Exemplo de Categoria com Posts Vinculados
{
"message": "Category cannot be deleted because it has posts associated."
}
🧾 Arquivos Principais do Projeto
| Arquivo | Responsabilidade |
|---|---|
app/Models/Post.php |
Model de posts com relacionamento, casts e slug automático. |
app/Models/Category.php |
Model de categorias com relacionamento e slug automático. |
app/Http/Controllers/Api/PostController.php |
CRUD, filtros, paginação e respostas de posts. |
app/Http/Controllers/Api/CategoryController.php |
CRUD e validações de integridade das categorias. |
app/Http/Requests/PostRequest.php |
Validação dos dados de posts. |
app/Http/Requests/CategoryRequest.php |
Validação dos dados de categorias. |
app/Http/Resources/PostResource.php |
Padronização do JSON de posts. |
app/Http/Resources/CategoryResource.php |
Padronização do JSON de categorias. |
database/migrations/*create_categories_table.php |
Estrutura da tabela categories. |
database/migrations/*create_posts_table.php |
Estrutura da tabela posts. |
routes/api.php |
Rotas versionadas da API. |
routes/web.php |
Dashboard simples com rotas disponíveis. |
✅ Checklist de Entrega
| Item Obrigatório | Situação |
|---|---|
| Link do repositório | Atendido. |
| README completo | Atendido por este arquivo. |
.env.example |
Atendido e deve ser versionado. |
.env real fora do Git |
Atendido pelo .gitignore. |
| Documentação das rotas | Atendido. |
| Exemplos JSON | Atendido. |
| Explicação das integrações | Atendido. |
| Fluxo principal do serviço | Atendido. |
| Como executar localmente | Atendido. |
| Como testar localmente | Atendido. |
| Dockerfile e docker-compose.yml | Não aplicável nesta entrega sem Docker. |
📚 Referências
📌 Observação Final
Este microserviço está funcional localmente e foi testado com rotas de health check, CRUD de categorias, CRUD de posts, filtros públicos, paginação, slugs automáticos, status de publicação e posts em destaque.