Documentação da API com Scribe
Documentação da API com Scribe
Este documento explica como usar e manter a documentação da API do AgrSis usando o Scribe.
Índice
- O que é o Scribe?
- Acessando a Documentação
- Como Adicionar/Atualizar Documentação
- Tipos de Anotações
- Exemplos Práticos
- Comandos Úteis
- Exportação para Outras Ferramentas
- Configuração Avançada
O que é o Scribe?
Scribe é um pacote Laravel que gera automaticamente documentação interativa para sua API a partir das anotações nos controllers.
Principais Funcionalidades:
- Documentação HTML interativa
- Exportação para Postman (collection.json)
- Exportação para OpenAPI/Swagger (openapi.yaml)
- Exemplos de requisições em múltiplas linguagens (Bash, JavaScript, PHP, Python)
- Teste de endpoints direto na documentação (Try It Out)
- Suporte a autenticação (Sanctum, Passport, etc.)
Acessando a Documentação
Localmente (Desenvolvimento)
Após iniciar o servidor:
php artisan serve
Acesse:
- Documentação HTML: http://localhost:8000/docs
- Postman Collection: http://localhost:8000/docs.postman
- OpenAPI Spec: http://localhost:8000/docs.openapi
Com Docker
docker-compose up -d
Acesse:
- Documentação HTML: http://localhost:8000/docs
Arquivos Exportados
Os arquivos exportados ficam em:
- Postman Collection:
storage/app/private/scribe/collection.json - OpenAPI Spec:
storage/app/private/scribe/openapi.yaml
Como Adicionar/Atualizar Documentação
Passo 1: Adicionar Anotações no Controller
Adicione anotações PHP DocBlock acima dos métodos do controller:
/**
* @group Nome do Grupo
*
* Descrição do grupo de endpoints
*/
class SeuController extends Controller
{
/**
* Título do Endpoint
*
* Descrição detalhada do que o endpoint faz.
*
* @authenticated
*
* @urlParam id integer required ID do recurso. Example: 1
* @queryParam filter string Filtro opcional. Example: ativo
* @bodyParam nome string required Nome do recurso. Example: João Silva
*
* @response 200 {
* "success": true,
* "data": {...}
* }
*/
public function index(Request $request)
{
// ...
}
}
Passo 2: Gerar a Documentação
Após adicionar ou modificar anotações, execute:
php artisan scribe:generate
Com Docker:
docker exec agrsis_api php artisan scribe:generate
Passo 3: Verificar
Acesse http://localhost:8000/docs para ver as alterações.
Tipos de Anotações
@group
Define o grupo ao qual o endpoint pertence. Geralmente usado na classe do controller.
/**
* @group Autenticação
*
* Endpoints relacionados à autenticação de usuários
*/
class AuthController extends Controller
@authenticated / @unauthenticated
Indica se o endpoint requer autenticação ou não.
/**
* @authenticated
*/
public function index() // Requer autenticação
/**
* @unauthenticated
*/
public function login() // Não requer autenticação
@urlParam
Parâmetros na URL (path parameters).
/**
* @urlParam id integer required ID do produto. Example: 1
* @urlParam slug string Slug do produto. Example: fertilizante-npk
*/
Formato: @urlParam nome tipo [required] descrição. Example: valor
@queryParam
Parâmetros de query string (?param=valor).
/**
* @queryParam page integer Número da página. Example: 1
* @queryParam per_page integer Itens por página. Example: 15
* @queryParam search string Termo de busca. Example: fertilizante
* @queryParam ativo boolean required Filtrar por status ativo. Example: true
*/
Formato: @queryParam nome tipo [required] descrição. Example: valor
@bodyParam
Parâmetros no corpo da requisição (POST/PUT/PATCH).
/**
* @bodyParam nome string required Nome do produto. Example: Fertilizante NPK
* @bodyParam descricao string Descrição do produto. Example: Fertilizante mineral misto
* @bodyParam preco number required Preço. Example: 150.50
* @bodyParam ativo boolean Status. Example: true
* @bodyParam categorias array Lista de categorias. Example: ["fertilizantes", "npk"]
*/
Formato: @bodyParam nome tipo [required] descrição. Example: valor
Tipos suportados:
stringinteger/intnumber/float/doubleboolean/boolarrayobjectfile
@response
Exemplo de resposta da API.
/**
* @response 200 {
* "success": true,
* "data": {
* "id": 1,
* "nome": "Produto A"
* }
* }
*
* @response 404 {
* "success": false,
* "message": "Recurso não encontrado"
* }
*/
Múltiplas respostas:
/**
* @response 200 scenario="Sucesso" {
* "success": true,
* "data": {...}
* }
*
* @response 401 scenario="Não autenticado" {
* "message": "Unauthenticated"
* }
*
* @response 422 scenario="Validação falhou" {
* "message": "The given data was invalid.",
* "errors": {...}
* }
*/
@header
Headers customizados para a requisição.
/**
* @header X-Custom-Header valor
* @header Accept-Language pt-BR
*/
@responseFile
Usar um arquivo JSON como resposta.
/**
* @responseFile storage/responses/produtos.json
* @responseFile 404 storage/responses/not-found.json
*/
Exemplos Práticos
Exemplo 1: Endpoint de Login (Não Autenticado)
/**
* @group Autenticação
*
* APIs para autenticação de usuários
*/
class AuthController extends Controller
{
/**
* Login
*
* Realiza autenticação do usuário e retorna um token de acesso.
*
* @unauthenticated
*
* @bodyParam email string required Email do usuário. Example: produtor@agrsis.com.br
* @bodyParam password string required Senha do usuário. Example: senha123
*
* @response 200 {
* "success": true,
* "message": "Login realizado com sucesso",
* "data": {
* "user": {
* "id": 1,
* "name": "João Silva",
* "email": "produtor@agrsis.com.br"
* },
* "token": "1|abcdefghijklmnopqrstuvwxyz"
* }
* }
*
* @response 401 {
* "success": false,
* "message": "Credenciais inválidas"
* }
*/
public function login(Request $request)
{
// ...
}
}
Exemplo 2: Endpoint CRUD (Autenticado)
/**
* @group Produtos
*
* APIs para gerenciamento de produtos
*/
class ProdutoController extends Controller
{
/**
* Listar Produtos
*
* Retorna uma lista paginada de produtos.
*
* @authenticated
*
* @queryParam page integer Número da página. Example: 1
* @queryParam per_page integer Itens por página. Example: 15
* @queryParam search string Buscar no nome. Example: fertilizante
*
* @response 200 {
* "success": true,
* "data": {
* "current_page": 1,
* "data": [
* {
* "id": 1,
* "nome": "Fertilizante NPK 10-10-10",
* "preco": 150.50
* }
* ],
* "total": 50
* }
* }
*/
public function index(Request $request)
{
// ...
}
/**
* Criar Produto
*
* Cria um novo produto no sistema.
*
* @authenticated
*
* @bodyParam nome string required Nome do produto. Example: Fertilizante NPK 20-05-20
* @bodyParam descricao string Descrição do produto. Example: Fertilizante mineral misto
* @bodyParam preco number required Preço. Example: 175.50
*
* @response 201 {
* "success": true,
* "message": "Produto criado com sucesso",
* "data": {
* "id": 3,
* "nome": "Fertilizante NPK 20-05-20",
* "preco": 175.50
* }
* }
*
* @response 422 {
* "message": "The given data was invalid.",
* "errors": {
* "nome": ["O campo nome é obrigatório."]
* }
* }
*/
public function store(Request $request)
{
// ...
}
}
Exemplo 3: Upload de Arquivo
/**
* Upload de Imagem
*
* Faz upload de uma imagem do produto.
*
* @authenticated
*
* @urlParam id integer required ID do produto. Example: 1
* @bodyParam imagem file required Arquivo de imagem (JPG, PNG). Example: /path/to/image.jpg
*
* @response 200 {
* "success": true,
* "message": "Imagem enviada com sucesso",
* "data": {
* "url": "https://exemplo.com/storage/produtos/imagem.jpg"
* }
* }
*/
public function uploadImagem(Request $request, $id)
{
// ...
}
Comandos Úteis
Gerar Documentação
# Local
php artisan scribe:generate
# Docker
docker exec agrsis_api php artisan scribe:generate
Limpar Cache da Documentação
# Local
rm -rf .scribe/endpoints.cache/*
php artisan scribe:generate
# Docker
docker exec agrsis_api rm -rf .scribe/endpoints.cache/*
docker exec agrsis_api php artisan scribe:generate
Publicar Configuração (já feito)
php artisan vendor:publish --tag=scribe-config
Atualizar Scribe
composer update knuckleswtf/scribe
Exportação para Outras Ferramentas
Importar no Postman
- Acesse: http://localhost:8000/docs.postman
- Copie o conteúdo JSON
- No Postman:
Import→Raw text→ Cole o JSON →Continue→Import
Ou baixe diretamente:
# Copiar collection para área de trabalho
cp storage/app/private/scribe/collection.json ~/Desktop/agrsis-api-postman.json
Importar no Insomnia
O Insomnia suporta OpenAPI:
- Acesse: http://localhost:8000/docs.openapi
- Copie o conteúdo YAML
- No Insomnia:
Create→Import From→URL/File→ Cole ou selecione arquivo
Ou baixe diretamente:
# Copiar OpenAPI spec para área de trabalho
cp storage/app/private/scribe/openapi.yaml ~/Desktop/agrsis-api-openapi.yaml
Swagger UI
Você pode usar o arquivo OpenAPI em qualquer Swagger UI:
# Exemplo com Docker
docker run -p 8080:8080 -e SWAGGER_JSON=/app/openapi.yaml \
-v $(pwd)/storage/app/private/scribe/openapi.yaml:/app/openapi.yaml \
swaggerapi/swagger-ui
Acesse: http://localhost:8080
Configuração Avançada
Arquivo de Configuração
O arquivo de configuração fica em: config/scribe.php
Principais Configurações
Título e Descrição
'title' => 'AgrSis API',
'description' => 'API da plataforma AgrSis - Sistema de Licitação Eletrônica',
URL Base
'base_url' => config('app.url'),
// Ou fixo: 'base_url' => 'https://api.agrsis.com.br',
Tipo de Documentação
'type' => 'laravel', // ou 'static'
- laravel: Gera views Blade (recomendado)
- static: Gera HTML estático em
public/docs
Autenticação
'auth' => [
'enabled' => true,
'default' => true, // Todos endpoints autenticados por padrão
'in' => 'bearer', // bearer, header, query, body
'name' => 'Authorization',
'placeholder' => '{SEU_TOKEN_SANCTUM}',
],
Linguagens de Exemplo
'example_languages' => [
'bash',
'javascript',
'php',
'python',
],
Rotas a Documentar
'routes' => [
[
'match' => [
'prefixes' => ['api/*'], // Apenas rotas que começam com api/
],
'exclude' => [
// 'GET /health', // Exemplo de exclusão
],
],
],
Try It Out
'try_it_out' => [
'enabled' => true,
'base_url' => null, // null usa o base_url da config
'use_csrf' => false, // true se usar Sanctum SPA
'csrf_url' => '/sanctum/csrf-cookie',
],
Logo Customizado
// Em config/scribe.php
'logo' => 'img/logo.png', // Arquivo em public/img/logo.png
Grupos Customizados
'groups' => [
'default' => 'Endpoints',
'order' => [
'Autenticação',
'Produtos',
'Cotações',
'Pedidos',
],
],
Estrutura de Arquivos
api/
├── .scribe/ # Cache e arquivos intermediários
│ ├── endpoints/ # Endpoints processados
│ ├── endpoints.cache/ # Cache de endpoints
│ ├── auth.md # Texto de autenticação
│ └── intro.md # Texto de introdução
│
├── config/
│ └── scribe.php # Configuração do Scribe
│
├── resources/views/scribe/ # Views Blade da documentação
│
├── public/vendor/scribe/ # Assets (CSS, JS)
│
├── storage/app/private/scribe/
│ ├── collection.json # Postman Collection
│ └── openapi.yaml # OpenAPI Spec
│
└── README_SCRIBE.md # Este arquivo
Boas Práticas
1. Sempre Gere Após Alterações
# Após modificar controllers
php artisan scribe:generate
2. Use Exemplos Realistas
/**
* @bodyParam nome string required Nome do produto. Example: Fertilizante NPK 10-10-10
*/
Evite exemplos genéricos como "string", "123", etc.
3. Documente Todos os Cenários
/**
* @response 200 scenario="Sucesso" {...}
* @response 401 scenario="Não autenticado" {...}
* @response 403 scenario="Sem permissão" {...}
* @response 404 scenario="Não encontrado" {...}
* @response 422 scenario="Validação falhou" {...}
*/
4. Agrupe Endpoints Logicamente
/**
* @group Autenticação
*/
/**
* @group Produtos
* @subgroup Categorias
*/
5. Use Descrições Claras
/**
* Listar Produtos Ativos
*
* Retorna uma lista paginada de produtos ativos no sistema,
* com suporte a filtros e busca por nome ou categoria.
*/
6. Mantenha Sincronizado
- Sempre que adicionar/remover endpoints, atualize a documentação
- Revise a documentação periodicamente
- Teste os exemplos para garantir que estão corretos
Troubleshooting
Problema: Endpoint não aparece na documentação
Solução:
- Verifique se a rota está em
routes/api.php - Confirme que o prefixo está em
config/scribe.php→routes.match.prefixes - Limpe o cache:
rm -rf .scribe/endpoints.cache/* - Gere novamente:
php artisan scribe:generate
Problema: Try It Out não funciona
Solução:
- Verifique
try_it_out.enabledemconfig/scribe.php - Configure CORS se a API estiver em domínio diferente
- Verifique se a URL base está correta
Problema: Autenticação não funciona nos exemplos
Solução:
- Configure
auth.enabled = trueemconfig/scribe.php - Verifique
auth.in(deve ser 'bearer' para Sanctum) - Use
@authenticatednos métodos
Problema: Erro ao gerar documentação
Solução:
- Verifique sintaxe das anotações
- Execute:
php artisan route:clear && php artisan config:clear - Verifique logs:
storage/logs/laravel.log
Links Úteis
- Documentação Oficial: https://scribe.knuckles.wtf/laravel
- GitHub: https://github.com/knuckleswtf/scribe
- Exemplos: https://scribe.knuckles.wtf/laravel/examples
Conclusão
O Scribe torna a documentação da API uma tarefa simples e automatizada. Basta adicionar anotações nos controllers e gerar a documentação.
Checklist Rápido
- Adicionar anotações
@groupna classe do controller - Adicionar anotações
@authenticatedou@unauthenticatednos métodos - Documentar parâmetros com
@urlParam,@queryParam,@bodyParam - Adicionar exemplos de resposta com
@response - Gerar documentação:
php artisan scribe:generate - Testar acessando http://localhost:8000/docs
Qualquer dúvida, consulte este README ou a documentação oficial!
Última atualização: 2025-12-04 Versão Scribe: 5.6.0 Versão Laravel: 11