<h2>O que é OpenAPI e Swagger?</h2>
<p>OpenAPI é uma especificação aberta para descrever APIs REST de forma padronizada e legível por máquinas. Swagger, na verdade, é o nome da ferramenta que surgiu antes da especificação OpenAPI ser oficializada pela Linux Foundation. Hoje, Swagger refere-se ao conjunto de ferramentas do SmartBear que implementam a especificação OpenAPI, incluindo a famosa interface Swagger UI para visualizar e testar endpoints.</p>
<p>Quando você documenta uma API com OpenAPI/Swagger, está criando um contrato que descreve todos os endpoints, parâmetros, respostas, autenticação e modelos de dados. Esse documento pode ser consumido por clientes, geradores de código e ferramentas de teste automaticamente, economizando tempo e reduzindo erros de integração.</p>
<h2>Configurando OpenAPI em um Projeto PHP</h2>
<h3>Instalação e Dependências</h3>
<p>A forma mais prática de trabalhar com OpenAPI em PHP é usar a biblioteca <code>zircote/swagger-php</code>, que lê anotações diretamente do seu código. Instale via Composer:</p>
<pre><code class="language-bash">composer require zircote/swagger-php</code></pre>
<p>Também vamos usar o <code>swagger-ui</code> para visualizar a documentação:</p>
<pre><code class="language-bash">composer require swagger-api/swagger-ui</code></pre>
<h3>Estrutura Básica com Anotações</h3>
<p>No Swagger-PHP, você documenta sua API usando anotações PHP. Aqui está um exemplo de um controlador simples com dois endpoints:</p>
<pre><code class="language-php"><?php
namespace App\Controllers;
/**
- @OA\Info(title="API de Produtos", version="1.0.0")
- @OA\Server(url="http://localhost:8000", description="Servidor de desenvolvimento")
*/
class ProdutoController
{
/**
- @OA\Get(
- path="/api/produtos",
- summary="Lista todos os produtos",
- @OA\Response(
- response=200,
- description="Lista de produtos retornada com sucesso",
- @OA\JsonContent(
- type="array",
- @OA\Items(ref="#/components/schemas/Produto")
- )
- )
- )
*/
public function listar()
{
return json_encode([
['id' => 1, 'nome' => 'Notebook', 'preco' => 2500.00],
['id' => 2, 'nome' => 'Mouse', 'preco' => 50.00]
]);
}
/**
- @OA\Post(
- path="/api/produtos",
- summary="Criar novo produto",
- @OA\RequestBody(
- required=true,
- @OA\JsonContent(ref="#/components/schemas/ProdutoCreate")
- ),
- @OA\Response(
- response=201,
- description="Produto criado com sucesso",
- @OA\JsonContent(ref="#/components/schemas/Produto")
- )
- )
*/
public function criar()
{
$dados = json_decode(file_get_contents('php://input'), true);
return json_encode(['id' => 3, 'nome' => $dados['nome'], 'preco' => $dados['preco']]);
}
}</code></pre>
<h3>Definindo Schemas de Dados</h3>
<p>Os schemas descrevem a estrutura dos seus objetos. Defina-os como classes com anotações:</p>
<pre><code class="language-php"><?php
namespace App\Models;
/**
- @OA\Schema(
- schema="Produto",
- type="object",
- required={"id", "nome", "preco"},
- @OA\Property(property="id", type="integer", example=1),
- @OA\Property(property="nome", type="string", example="Notebook"),
- @OA\Property(property="preco", type="number", format="float", example=2500.00)
- )
*/
class Produto
{
public int $id;
public string $nome;
public float $preco;
}
/**
- @OA\Schema(
- schema="ProdutoCreate",
- type="object",
- required={"nome", "preco"},
- @OA\Property(property="nome", type="string", example="Teclado"),
- @OA\Property(property="preco", type="number", format="float", example=150.00)
- )
*/
class ProdutoCreate
{
public string $nome;
public float $preco;
}</code></pre>
<h2>Gerando e Servindo a Documentação</h2>
<h3>Gerando o JSON do OpenAPI</h3>
<p>Crie um script PHP na raiz do projeto (ex: <code>openapi.php</code>) que gera o arquivo de especificação:</p>
<pre><code class="language-php"><?php
require_once __DIR__ . '/vendor/autoload.php';
use OpenAPI\Generator;
$openapi = Generator::scan([__DIR__ . '/app']);
header('Content-Type: application/json');
echo json_encode($openapi->toArray(), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);</code></pre>
<p>Execute via CLI: <code>php openapi.php > openapi.json</code></p>
<h3>Servindo Swagger UI</h3>
<p>Copie o Swagger UI para sua pasta pública e crie um arquivo <code>swagger.html</code>:</p>
<pre><code class="language-html"><!DOCTYPE html>
<html>
<head>
<title>API Documentation</title>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swagger-ui-dist@3/swagger-ui.css">
</head>
<body>
<div id="swagger-ui"></div>
<script src="https://cdn.jsdelivr.net/npm/swagger-ui-dist@3/swagger-ui.bundle.js"></script>
<script>
SwaggerUIBundle({
url: "/openapi.json",
dom_id: '#swagger-ui',
presets: [SwaggerUIBundle.presets.apis, SwaggerUIBundle.SwaggerUIStandalonePreset]
});
</script>
</body>
</html></code></pre>
<h2>Boas Práticas e Dicas Práticas</h2>
<p>Documente parâmetros de query e path de forma clara. Se seu endpoint recebe filtros, declare-os explicitamente com suas restrições:</p>
<pre><code class="language-php">/**
- @OA\Get(
- path="/api/produtos",
- @OA\Parameter(
- name="categoria",
- in="query",
- description="Filtrar por categoria",
- @OA\Schema(type="string")
- ),
- @OA\Parameter(
- name="preco_max",
- in="query",
- description="Preço máximo",
- @OA\Schema(type="number", format="float")
- )
- )
*/
public function filtrar() { }</code></pre>
<p>Sempre documente códigos de erro e exceções. Use diferentes status codes (400, 401, 404, 500) e descreva o que cada um significa em seu contexto. Mantenha a documentação atualizada junto com o código — quando você muda um endpoint, atualize a anotação imediatamente. Isso evita que a documentação fique obsoleta e confunda quem está consumindo a API.</p>
<h2>Conclusão</h2>
<p>Documentar APIs com OpenAPI/Swagger em PHP não é apenas bom para seus usuários — é um investimento na qualidade e manutenibilidade do seu código. Você aprende que a especificação OpenAPI funciona como um contrato vivo entre seu código e seus consumidores, mantendo tudo sincronizado. Swagger-PHP transforma suas anotações em documentação interativa automaticamente, economizando horas de esforço manual. Por fim, a Swagger UI oferece uma interface testável onde qualquer desenvolvedor pode explorar seus endpoints sem abrir uma única linha de código.</p>
<h2>Referências</h2>
<ul>
<li><a href="https://spec.openapis.org/oas/v3.0.3" target="_blank" rel="noopener noreferrer">OpenAPI Specification Oficial</a></li>
<li><a href="https://github.com/zircote/swagger-php" target="_blank" rel="noopener noreferrer">Swagger-PHP Documentation</a></li>
<li><a href="https://github.com/swagger-api/swagger-ui" target="_blank" rel="noopener noreferrer">Swagger UI GitHub</a></li>
<li><a href="https://swagger.io/resources/articles/best-practices-in-api-documentation/" target="_blank" rel="noopener noreferrer">Best Practices for Documenting APIs</a></li>
<li><a href="https://smartbear.com/blog/api-design/documenting-apis-with-openapi/" target="_blank" rel="noopener noreferrer">PHP OpenAPI Guide - SmartBear</a></li>
</ul>