DEV Community

Cover image for Plataforma API para Workflow API Design-First
Lucas
Lucas

Posted on • Originally published at apidog.com

Plataforma API para Workflow API Design-First

TL;DR

A abordagem design-first significa escrever a especificação da API antes do código de implementação. Essa especificação passa a orientar mocks, documentação, testes e stubs de cliente. Ao usar uma plataforma que cobre esse fluxo de ponta a ponta, você reduz o atrito de manter código, documentação e contratos sincronizados.

Experimente o Apidog hoje

Apidog

Experimente o Apidog gratuitamente

Introdução

A maioria dos desenvolvedores começa criando APIs com uma abordagem code-first:

  1. Escreve uma rota.
  2. Adiciona anotações ou decorators.
  3. Gera documentação.
  4. Ajusta conforme o código evolui.

Isso funciona em projetos pequenos. O problema aparece quando a API cresce.

A documentação se desvia. As anotações ficam desatualizadas. Um endpoint muda o formato da resposta, mas a especificação não é atualizada. Meses depois, o frontend consome uma documentação que diz que a API retorna um array de strings, enquanto a resposta real retorna um array de objetos com um campo value.

No design-first, a especificação é a fonte da verdade. Código, documentação, mocks e testes partem dela. Quando a especificação muda, todo o fluxo acompanha essa mudança.

Na prática, isso permite:

  • Desenvolvimento frontend e backend em paralelo.
  • Mocks disponíveis antes da implementação.
  • Documentação sempre alinhada ao contrato.
  • Testes de contrato para detectar divergências.
  • Revisão explícita de mudanças na API.

O ponto crítico é a ferramenta. Se escrever a especificação for mais lento do que implementar a rota diretamente, a equipe tende a ignorar o processo. Uma boa plataforma design-first precisa tornar a criação do contrato rápida, visual e integrada ao restante do ciclo de desenvolvimento.


O que design-first significa na prática

Design-first não é uma tecnologia específica. É um fluxo de trabalho.

A ideia central é simples:

Defina o contrato da API antes de implementar a API.

Esse contrato geralmente é escrito em OpenAPI para APIs REST.

Antes de escrever código

Comece definindo a especificação da API. Ela deve incluir:

  • Caminhos e métodos HTTP.
  • Parâmetros de path, query e headers.
  • Schemas de request body para POST, PUT e PATCH.
  • Schemas de resposta para status como 200, 400, 401, 422 e 500.
  • Requisitos de autenticação.
  • Descrições de campos.
  • Exemplos de payloads.

Exemplo simplificado de especificação OpenAPI:

openapi: 3.0.3
info:
  title: "Users API"
  version: 1.0.0

paths:
  /users/{id}:
    get:
      summary: Buscar usuário por ID
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: "Usuário encontrado"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UserProfile"
        "404":
          description: "Usuário não encontrado"

components:
  schemas:
    UserProfile:
      type: object
      required:
        - id
        - name
        - email
      properties:
        id:
          type: string
          example: "usr_123"
        name:
          type: string
          example: "Ana Silva"
        email:
          type: string
          format: email
          example: "ana@example.com"
Enter fullscreen mode Exit fullscreen mode

Essa etapa força decisões importantes antes da implementação:

  • Como os recursos serão nomeados.
  • Qual será o formato dos erros.
  • Como paginação será representada.
  • Quais campos são obrigatórios.
  • Quais status HTTP serão usados.
  • Como autenticação será aplicada.

Durante o desenvolvimento

Depois que a especificação existe, publique um mock baseado nela.

Com isso:

  • O frontend consome a URL mockada.
  • O backend implementa seguindo o contrato.
  • Ambos trabalham em paralelo.
  • A integração começa antes da API real estar pronta.

Exemplo de fluxo:

1. Equipe define GET /users/{id} na especificação
2. Mock é gerado automaticamente
3. Frontend usa o mock para construir a tela
4. Backend implementa o endpoint real
5. Testes validam se a resposta real segue o schema
Enter fullscreen mode Exit fullscreen mode

Após a implementação

A implementação deve ser validada contra a especificação.

Por exemplo, se a especificação diz que email é obrigatório e a API real não retorna esse campo, o teste deve falhar.

Esse tipo de validação evita que divergências cheguem ao ambiente de produção.

Quando os requisitos mudam

A ordem correta é:

  1. Atualizar a especificação.
  2. Revisar a mudança com as partes envolvidas.
  3. Atualizar mocks e documentação.
  4. Ajustar implementação.
  5. Rodar testes de contrato.

A implementação não deve mudar silenciosamente sem atualizar o contrato.


O que uma plataforma design-first precisa oferecer

Nem toda ferramenta de API suporta bem fluxos design-first. Para funcionar no dia a dia, a plataforma precisa cobrir mais do que edição de YAML.

Editor visual de API

YAML puro é útil, mas não é a melhor interface para design colaborativo.

Um bom editor visual deve permitir configurar:

  • Método HTTP.
  • Path.
  • Parâmetros.
  • Headers.
  • Body.
  • Responses.
  • Schemas.
  • Exemplos.
  • Regras de validação.

Também deve gerar OpenAPI válido sem exigir que a equipe escreva tudo manualmente.

Validação OpenAPI em tempo real

A especificação precisa ser válida antes de ser usada para mocks, documentação ou geração de código.

A ferramenta deve indicar problemas como:

  • Campos obrigatórios ausentes.
  • Referências $ref quebradas.
  • Tipos inválidos.
  • Responses sem schema.
  • Parâmetros declarados no path, mas não definidos.

Isso evita descobrir erros apenas no CI ou no momento da integração.

Mock automático a partir da especificação

O mock deve ser gerado diretamente da especificação, sem configuração duplicada.

Fluxo ideal:

Criar endpoint → Definir schema → Salvar → Obter URL mockada
Enter fullscreen mode Exit fullscreen mode

O mock deve respeitar:

  • Tipos de campos.
  • Formatos como email, date, uuid.
  • Valores mínimos e máximos.
  • Enums.
  • Arrays.
  • Objetos aninhados.
  • Schemas reutilizáveis via $ref.

Documentação com pré-visualização

A documentação deve ser derivada da especificação.

Durante o design, a equipe deve conseguir revisar:

  • Descrição do endpoint.
  • Parâmetros.
  • Payloads.
  • Schemas.
  • Exemplos de request e response.
  • Códigos de erro.

Isso ajuda frontend, backend, QA, produto e integrações externas a validarem o contrato antes da implementação.

Revisão em equipe

Mudanças em APIs devem ser tratadas como mudanças de código.

Uma plataforma design-first deve permitir:

  • Comentários em endpoints.
  • Discussões em campos específicos.
  • Histórico de alterações.
  • Revisão assíncrona.
  • Visibilidade sobre quem alterou o quê.

Exportação para OpenAPI padrão

A especificação precisa ser portátil.

Você deve conseguir exportar OpenAPI 3.x e usar com outras ferramentas, como:

  • Geradores de código.
  • Gateways de API.
  • Validadores.
  • Test runners.
  • Ferramentas de documentação.
  • Pipelines de CI/CD.

Apidog como plataforma design-first

O Apidog organiza o fluxo em torno da especificação da API. Design, mock, documentação, testes e colaboração usam a mesma definição de API como base.

Editor visual OpenAPI

No Apidog, cada endpoint é editado em uma interface estruturada.

Você configura:

  • Path.
  • Método HTTP.
  • Parâmetros.
  • Headers.
  • Body.
  • Responses.
  • Schemas.
  • Descrições.
  • Exemplos.
  • Regras de validação.

Isso reduz a necessidade de escrever YAML manualmente.

Ainda assim, se preferir, é possível visualizar e editar a representação bruta em YAML ou JSON. As alterações feitas na visualização visual e na visualização bruta permanecem sincronizadas.

Reutilização com componentes

Componentes de schema são essenciais para evitar duplicação.

Exemplo:

components:
  schemas:
    ErrorResponse:
      type: object
      required:
        - code
        - message
      properties:
        code:
          type: string
          example: "USER_NOT_FOUND"
        message:
          type: string
          example: "Usuário não encontrado"
Enter fullscreen mode Exit fullscreen mode

Depois, o mesmo schema pode ser referenciado em vários endpoints:

responses:
  "404":
    description: Usuário não encontrado
    content:
      application/json:
        schema:
          $ref: "#/components/schemas/ErrorResponse"
Enter fullscreen mode Exit fullscreen mode

No Apidog, esses componentes podem ser definidos uma vez e reutilizados em múltiplas rotas. Ao alterar o schema, os endpoints que o referenciam refletem a mudança.

Pré-visualização de documentação em tempo real

Enquanto você projeta um endpoint, a documentação pode ser pré-visualizada.

Isso permite validar rapidamente:

  • Se os nomes dos campos estão claros.
  • Se os exemplos fazem sentido.
  • Se os status HTTP estão documentados.
  • Se os erros estão compreensíveis.
  • Se a estrutura do payload é fácil de consumir.

Essa pré-visualização é útil para revisar a API com frontend, QA, produto ou times externos antes de implementar o backend.

Smart Mock: da especificação para um mock funcional

Ao salvar um endpoint no Apidog, o servidor de mock fica disponível.

O mock gera respostas com base nos schemas definidos. Por exemplo:

  • Campos string com format: email retornam emails válidos.
  • Campos integer com minimum e maximum retornam valores dentro do intervalo.
  • Campos enum retornam um dos valores permitidos.
  • Arrays e objetos aninhados seguem a estrutura definida.
  • Schemas com $ref são resolvidos corretamente.

Exemplo de schema:

UserProfile:
  type: object
  properties:
    id:
      type: string
      example: "usr_123"
    email:
      type: string
      format: email
    role:
      type: string
      enum:
        - admin
        - member
        - viewer
Enter fullscreen mode Exit fullscreen mode

O mock pode retornar algo compatível com esse contrato:

{
  "id": "usr_123",
  "email": "user@example.com",
  "role": "member"
}
Enter fullscreen mode Exit fullscreen mode

Também é possível configurar regras de mock para cenários específicos, como:

  • Retornar 404 quando id = 0.
  • Retornar um payload específico para determinado parâmetro de query.
  • Simular respostas de erro.
  • Testar estados vazios.

Revisão em equipe e histórico de mudanças

Mudanças na especificação ficam visíveis para os membros do workspace.

A equipe pode comentar em endpoints ou campos específicos e acompanhar o histórico de alterações.

Para um fluxo design-first, isso ajuda a manter uma prática importante:

Nenhuma mudança de contrato deve acontecer sem visibilidade para quem consome a API.


Design-first vs. code-first: compensações reais

Design-first não é sempre a melhor escolha. A decisão depende do contexto.

Vantagens do design-first

Use design-first quando você precisa de coordenação entre pessoas ou times.

Benefícios principais:

  • Frontend e backend trabalham em paralelo.
  • Mocks ficam disponíveis desde o início.
  • A documentação nasce junto com o contrato.
  • Mudanças são revisadas antes da implementação.
  • Testes conseguem validar a implementação contra o schema.
  • Problemas de integração aparecem mais cedo.

Desvantagens do design-first

O design-first também tem custos:

  • Exige tempo inicial para definir a especificação.
  • A equipe precisa aprender a ferramenta.
  • É necessário manter disciplina para não alterar a implementação sem atualizar o contrato.
  • Especificar demais muito cedo pode dificultar mudanças quando o domínio ainda está incerto.

Vantagens do code-first

Code-first pode ser melhor quando:

  • O projeto é pequeno.
  • Você está prototipando.
  • Há apenas um desenvolvedor.
  • A API ainda é experimental.
  • A velocidade de descoberta é mais importante do que a estabilidade do contrato.

Desvantagens do code-first

Os problemas aparecem conforme a API cresce:

  • Documentação tende a ficar desatualizada.
  • Frontend precisa esperar a implementação real.
  • O contrato fica implícito no código.
  • Mudanças quebram consumidores com mais facilidade.
  • Refatorações exigem atualização manual da documentação.

Como regra prática:

Projeto experimental ou solo → code-first pode ser suficiente
API consumida por múltiplos times → design-first tende a escalar melhor
Enter fullscreen mode Exit fullscreen mode

Ferramentas que suportam fluxos design-first

Apidog

O Apidog combina editor visual, mock, documentação, testes e revisão em equipe em uma única plataforma.

É uma boa opção para times que querem manter a especificação como fonte da verdade e usar o mesmo contrato para design, mock, validação e documentação.

Stoplight Studio

O Stoplight Studio oferece um editor OpenAPI forte e linting com Spectral para padronização.

É útil para organizações que precisam de governança de API. Porém, não foca no mesmo nível de integração entre mock, testes e fluxo completo de desenvolvimento.

SwaggerHub

O SwaggerHub é uma plataforma madura para edição e colaboração em OpenAPI.

É bastante usado em ambientes corporativos e funciona bem para organizações já inseridas no ecossistema Swagger. Sua capacidade de mock e testes é mais limitada em comparação com plataformas mais integradas.

Postman com API Builder

O Postman oferece recursos de design de API e geração de especificações OpenAPI.

Ainda assim, os fluxos de design e collections podem parecer separados. O mock geralmente exige configuração manual a partir de collections, em vez de nascer automaticamente da especificação.

Funciona bem para equipes code-first que querem adicionar documentação e alguns recursos de contrato.

Insomnia com modo de documento

O Insomnia permite editar especificações OpenAPI e oferece mock básico.

É uma opção leve para desenvolvedores solo, mas menos completa para fluxos design-first colaborativos.


Como configurar um fluxo design-first no Apidog

Passo 1: comece pela especificação

Crie um projeto e abra a área de design.

Antes de enviar qualquer request, defina pelo menos:

  • Path.
  • Método HTTP.
  • Parâmetros.
  • Schema de resposta.
  • Possíveis códigos de erro.

Exemplo mínimo:

GET /users/{id}

Path param:
- id: string, obrigatório

Responses:
- 200: UserProfile
- 404: ErrorResponse
Enter fullscreen mode Exit fullscreen mode

Passo 2: defina componentes compartilhados

Antes de criar muitos endpoints, padronize os schemas reutilizáveis.

Componentes comuns:

  • ErrorResponse
  • Pagination
  • UserProfile
  • AuthToken
  • ValidationError
  • Metadata

Exemplo:

Pagination:
  type: object
  properties:
    page:
      type: integer
      example: 1
    pageSize:
      type: integer
      example: 20
    total:
      type: integer
      example: 150
Enter fullscreen mode Exit fullscreen mode

Isso evita que cada endpoint implemente paginação ou erros de forma diferente.

Passo 3: salve o endpoint e use a URL de mock

Assim que o endpoint estiver salvo, copie a URL do mock e compartilhe com o frontend.

O frontend pode começar com algo como:

const response = await fetch("https://mock.example.com/users/usr_123");
const user = await response.json();

console.log(user.name);
Enter fullscreen mode Exit fullscreen mode

Mesmo que o backend ainda não esteja pronto, a interface já pode ser implementada usando o contrato.

Passo 4: revise a documentação antes do código

Abra a pré-visualização da documentação e valide:

  • O objetivo do endpoint está claro?
  • Os campos têm descrições úteis?
  • Os exemplos representam casos reais?
  • Os erros estão documentados?
  • O frontend tem informação suficiente para consumir a API?

Se algo não estiver claro na documentação, corrija na especificação antes da implementação.

Passo 5: bloqueie o contrato durante o sprint

Depois da revisão, trate a especificação como o contrato do sprint.

Se a implementação exigir uma mudança, não altere apenas o código. Faça o fluxo correto:

1. Propor alteração na especificação
2. Revisar impacto com consumidores da API
3. Atualizar mock e documentação
4. Ajustar backend
5. Validar com testes
Enter fullscreen mode Exit fullscreen mode

Isso evita que o frontend integre contra um comportamento diferente do planejado.

Passo 6: valide schemas no CI

Configure testes para garantir que a resposta real respeite o contrato.

Exemplo de validação esperada:

Endpoint: GET /users/{id}
Esperado:
- status 200
- body compatível com UserProfile
- campo email presente
- campo email no formato correto
Enter fullscreen mode Exit fullscreen mode

Em um pipeline, a ideia é:

Build → Deploy ambiente de teste → Executar testes de API → Validar schema → Aprovar ou falhar
Enter fullscreen mode Exit fullscreen mode

Esse passo mantém implementação e especificação sincronizadas ao longo do tempo.


FAQ

O design-first é apenas para APIs REST?

Não.

O princípio se aplica a qualquer tecnologia em que exista um contrato:

  • REST com OpenAPI.
  • GraphQL com schema-first.
  • gRPC com arquivos .proto.
  • Sistemas orientados a eventos com AsyncAPI.

O Apidog suporta design REST e GraphQL. Para gRPC, os arquivos proto cumprem o papel de contrato primeiro.

Precisamos definir todos os endpoints antes de começar?

Não.

Você pode adotar design-first por recurso.

Por exemplo:

Sprint atual: módulo de usuários
Defina primeiro apenas os endpoints de usuários
Implemente backend e frontend em paralelo
Depois avance para o próximo módulo
Enter fullscreen mode Exit fullscreen mode

A adoção incremental funciona bem e reduz resistência da equipe.

Como design-first funciona com sprints ágeis?

No início do sprint, faça uma sessão curta de design da API.

Saída esperada:

  • Endpoints definidos.
  • Schemas revisados.
  • Mocks publicados.
  • Documentação inicial disponível.
  • Pontos de dúvida registrados.

Depois disso, frontend e backend trabalham em paralelo durante o sprint.

E se a implementação precisar divergir da especificação?

Isso pode acontecer.

O processo correto é:

  1. Atualizar a especificação.
  2. Revisar a mudança com os consumidores da API.
  3. Atualizar mocks e documentação.
  4. Alterar a implementação.
  5. Rodar os testes.

A especificação deve continuar sendo a fonte da verdade.

Podemos gerar stubs de servidor a partir da exportação OpenAPI do Apidog?

Sim.

Exporte a especificação como OpenAPI 3.x e use um gerador de código compatível.

Por exemplo, com openapi-generator:

openapi-generator-cli generate \
  -i openapi.yaml \
  -g nodejs-express-server \
  -o ./generated-server
Enter fullscreen mode Exit fullscreen mode

O openapi-generator suporta várias linguagens e frameworks.

Como lidar com versionamento da especificação?

O Apidog mantém histórico de mudanças dentro do projeto.

Para versões principais mantidas em paralelo, como v1 e v2, uma abordagem comum é usar projetos ou branches separados.

Exemplo:

API Users v1 → projeto/branch estável
API Users v2 → projeto/branch em evolução
Enter fullscreen mode Exit fullscreen mode

Conclusão

Design-first exige um pequeno investimento inicial em disciplina, mas reduz custos de integração conforme a API cresce.

O fluxo recomendado é:

Especificar → Revisar → Mockar → Implementar → Testar → Documentar automaticamente
Enter fullscreen mode Exit fullscreen mode

A ferramenta escolhida precisa tornar esse fluxo simples. Se escrever a especificação for difícil, a equipe volta para code-first.

Com editor visual, mock instantâneo, documentação em tempo real e testes conectados ao mesmo contrato, o Apidog torna o design-first mais prático para equipes que precisam construir APIs de forma colaborativa e previsível.

Top comments (0)