Como Usar a API Zuplo: Guia Completo

Ashley Innocent

Ashley Innocent

27 abril 2026

Como Usar a API Zuplo: Guia Completo

Se você leu sobre o Zuplo e quer colocar algo real em produção com ele, este é o post para você. A plataforma é rápida de aprender, mas a documentação está espalhada por fluxos de portal, comandos CLI e artigos do centro de aprendizagem. Este guia une as peças em um único tutorial: crie um projeto, exponha uma rota, adicione autenticação com chave de API e limitação de taxa, escreva uma política TypeScript personalizada, faça o deploy para a edge e teste tudo com o Apidog.

botão

Ao final, você terá um gateway de API funcional rodando na frente da sua origem, com autenticação, limitação de taxa, um portal do desenvolvedor auto-gerado e um fluxo de trabalho Git amigável para CI. Todo o passo a passo leva cerca de trinta minutos.

Se você ainda está decidindo se o Zuplo é a ferramenta certa, comece com nosso post complementar: O que é o gateway de API Zuplo. Para todo o resto, a documentação do Zuplo cobre casos de uso que este guia não aborda.

TL;DR

Pré-requisitos

Você precisa de três coisas antes de começar:

Para desenvolvimento local, você também precisa de um editor de código. O VS Code com a extensão TypeScript é o caminho de menor resistência, e você pode combiná-lo com a extensão Apidog VS Code para fazer requisições sem sair do seu editor.

Passo 1: Crie seu projeto Zuplo

Você tem duas maneiras de começar: o portal web ou o CLI. A maioria das equipes começa no portal porque é mais rápido para demonstrações, e depois migra para o CLI quando querem CI/CD.

Opção A: Primeiro o Portal

  1. Faça login em portal.zuplo.com.
  2. Clique em "New Project" (Novo Projeto) e escolha um nome como acme-gateway.
  3. Escolha "Empty Project" (Projeto Vazio) para que nada seja criado automaticamente.
  4. A aba Code (Código) abre para uma estrutura de arquivos inicial.

O portal vincula o projeto a um repositório Git gerenciado por padrão. Você pode conectar seu próprio repositório GitHub, GitLab, Bitbucket ou Azure DevOps a partir das Configurações mais tarde.

Opção B: Primeiro o CLI

O CLI estrutura o mesmo layout de projeto localmente para que você possa editar em sua IDE e usar o Git desde o primeiro dia.

npm create zuplo@latest -- --name acme-gateway
cd acme-gateway
npm install
npm run dev

O servidor de desenvolvimento inicia na porta 9000 e imprime um link para o Route Designer local em http://localhost:9100. Qualquer alteração que você fizer no editor ou no designer recarrega imediatamente.

Para vincular o projeto local à sua conta Zuplo quando estiver pronto para o deploy:

npx zuplo link

Escolha a conta e o ambiente quando solicitado. A partir daqui, npx zuplo deploy envia a branch Git atual.

Passo 2: Defina sua primeira rota

Abra config/routes.oas.json. Este é um documento OpenAPI 3 com extensões Zuplo para handlers e políticas. Adicione uma rota que encaminhe GET /v1/products para sua origem:

{
  "openapi": "3.1.0",
  "info": { "title": "Acme Gateway", "version": "1.0.0" },
  "paths": {
    "/v1/products": {
      "get": {
        "summary": "List products",
        "operationId": "list-products",
        "x-zuplo-route": {
          "corsPolicy": "anything-goes",
          "handler": {
            "export": "urlForwardHandler",
            "module": "$import(@zuplo/runtime)",
            "options": {
              "baseUrl": "${env.ORIGIN_URL}"
            }
          },
          "policies": { "inbound": [] }
        },
        "responses": {
          "200": { "description": "Success" }
        }
      }
    }
  }
}

Alguns detalhes que valem a pena notar. A extensão x-zuplo-route é onde o Zuplo vive dentro de um arquivo OpenAPI que, de outra forma, seria padrão. O handler descreve o que acontece quando a rota corresponde; urlForwardHandler é o proxy embutido. A referência ${env.ORIGIN_URL} puxa das variáveis de ambiente para que você possa direcionar diferentes backends por ambiente.

Defina ORIGIN_URL em Settings > Environment Variables (Configurações > Variáveis de Ambiente) no portal, ou editando config/.env localmente. Use https://echo.zuplo.io se você ainda não tiver uma origem real.

Salve e o servidor de desenvolvimento local recarregará. Acesse http://localhost:9000/v1/products e você deverá ver a requisição ecoada. Gateways implantados responderão do centro de dados de edge mais próximo.

Passo 3: Adicione autenticação por chave de API

APIs públicas precisam de credenciais. O Zuplo oferece um serviço gerenciado de chave de API para que você não precise construir um armazenamento de chaves por conta própria.

Edite a rota para adicionar a política de entrada:

"policies": {
  "inbound": ["api-key-auth"]
}

Em seguida, adicione a definição da política a config/policies.json (o Zuplo cria este arquivo na primeira vez que você adiciona uma política):

{
  "name": "api-key-auth",
  "policyType": "api-key-inbound",
  "handler": {
    "export": "ApiKeyInboundPolicy",
    "module": "$import(@zuplo/runtime)",
    "options": {
      "allowUnauthenticatedRequests": false
    }
  }
}

Agora crie um consumidor (a entidade que possui uma ou mais chaves de API):

  1. Vá para Services > API Key Service (Serviços > Serviço de Chave de API) no portal.
  2. Clique em "Create Consumer" (Criar Consumidor).
  3. Defina o assunto para um identificador estável como acme-customer-1.
  4. Adicione o e-mail de quem deve gerenciar a chave.
  5. Copie a chave de API gerada.

Teste com curl. Sem o cabeçalho, você deverá ver um 401:

curl -i https://YOUR-PROJECT.zuplo.app/v1/products
# HTTP/2 401

Com o cabeçalho, você deverá ver a resposta 200 original:

curl -i https://YOUR-PROJECT.zuplo.app/v1/products \
  -H "Authorization: Bearer YOUR_API_KEY"
# HTTP/2 200

Se você preferir fazer isso a partir de um cliente real, importe a especificação OpenAPI do gateway para o Apidog, defina um cabeçalho global para Authorization: Bearer {{api_key}} e vincule api_key a uma variável de ambiente. Você obtém uma superfície de teste limpa para cada rota em segundos.

Passo 4: Limite a taxa da rota

Nunca coloque uma API pública em produção sem limites de taxa. A política de limite de taxa padrão do Zuplo oferece throttling por IP, por chave ou por atributo personalizado.

Adicione-o à lista de entrada, após a autenticação:

"policies": {
  "inbound": ["api-key-auth", "rate-limit-by-key"]
}

Defina-o em config/policies.json:

{
  "name": "rate-limit-by-key",
  "policyType": "rate-limit-inbound",
  "handler": {
    "export": "RateLimitInboundPolicy",
    "module": "$import(@zuplo/runtime)",
    "options": {
      "rateLimitBy": "sub",
      "requestsAllowed": 60,
      "timeWindowMinutes": 1
    }
  }
}

rateLimitBy: "sub" usa o assunto autenticado da política de chave de API como chave para o bucket, então cada cliente obtém seu próprio orçamento de 60 requisições por minuto. Substitua por "ip" se você quiser limitar o tráfego anônimo.

A 61ª requisição dentro de qualquer janela de sessenta segundos retorna 429 com cabeçalhos de repetição anexados. Teste disparando 70 requisições em um loop e observando os códigos de resposta mudarem.

for i in {1..70}; do
  curl -s -o /dev/null -w "%{http_code}\n" \
    https://YOUR-PROJECT.zuplo.app/v1/products \
    -H "Authorization: Bearer YOUR_API_KEY"
done | sort | uniq -c

Você deverá ver 60 linhas exibindo 200 e 10 exibindo 429.

Passo 5: Valide payloads de requisição

Se você tiver uma rota POST que aceita um corpo JSON, a política de validação de requisições captura payloads malformados no gateway em vez de na sua origem. Ela usa o JSON Schema embutido em sua operação OpenAPI, então você obtém isso de graça se sua especificação estiver precisa.

Adicione uma rota com um corpo de requisição:

"/v1/products": {
  "post": {
    "summary": "Create product",
    "operationId": "create-product",
    "requestBody": {
      "required": true,
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "required": ["name", "priceCents"],
            "properties": {
              "name": { "type": "string", "minLength": 1 },
              "priceCents": { "type": "integer", "minimum": 1 },
              "category": { "type": "string", "enum": ["food", "drink"] }
            }
          }
        }
      }
    },
    "x-zuplo-route": {
      "handler": { /* same as above */ },
      "policies": {
        "inbound": [
          "api-key-auth",
          "rate-limit-by-key",
          "validate-request"
        ]
      }
    }
  }
}

Adicione a política:

{
  "name": "validate-request",
  "policyType": "open-api-request-validation-inbound",
  "handler": {
    "export": "OpenApiRequestValidationInboundPolicy",
    "module": "$import(@zuplo/runtime)",
    "options": {
      "validateBody": "reject"
    }
  }
}

Agora, um POST com um campo ausente é rejeitado com um 400 antes de chegar à sua origem. Teste-o com o Apidog salvando uma requisição de "caminho feliz", uma requisição de "campo obrigatório ausente" e uma requisição de "valor de enumeração errado" como exemplos separados no mesmo grupo de requisições. Você pode executar todos os três com um clique.

Passo 6: Escreva uma política TypeScript personalizada

Políticas pré-construídas cobrem a maioria do que as equipes precisam. O objetivo do Zuplo, no entanto, é o momento em que você precisa de algo personalizado. Aqui está uma política de saída que adiciona um cabeçalho Cache-Control para clientes pagantes e no-store para os gratuitos.

Crie modules/tiered-cache.ts:

import { ZuploRequest, ZuploContext, HttpProblems } from "@zuplo/runtime";

interface PolicyOptions {
  paidPlanHeader: string;
  paidMaxAge: number;
}

export default async function (
  response: Response,
  request: ZuploRequest,
  context: ZuploContext,
  options: PolicyOptions,
): Promise<Response> {
  const plan = request.user?.data?.plan ?? "free";

  if (plan === "free") {
    response.headers.set("Cache-Control", "no-store");
  } else {
    response.headers.set(
      "Cache-Control",
      `public, max-age=${options.paidMaxAge}`,
    );
  }

  context.log.info(`Cache header set for plan=${plan}`);
  return response;
}

Conecte-o em config/policies.json:

{
  "name": "tiered-cache",
  "policyType": "custom-code-outbound",
  "handler": {
    "export": "default",
    "module": "$import(./modules/tiered-cache)",
    "options": {
      "paidPlanHeader": "x-plan",
      "paidMaxAge": 300
    }
  }
}

E referencie-o a partir da rota:

"policies": {
  "inbound": ["api-key-auth", "rate-limit-by-key"],
  "outbound": ["tiered-cache"]
}

A política personalizada é apenas uma função. Você pode testá-la unitariamente com Vitest ou Jest, passando um Response sintético e ZuploRequest e verificando os cabeçalhos, sem a necessidade de um harness de integração.

Passo 7: Faça o deploy para a edge

O deploy é um push Git.

git add .
git commit -m "Add products gateway with auth, rate limit, and tiered cache"
git push origin feature/products-gateway

O Zuplo constrói um ambiente de preview para cada branch e imprime a URL no log de build. O preview obtém seu próprio subdomínio como https://acme-gateway-feature-products-gateway-abc123.zuplo.app, com todas as suas políticas ativas e apontando para qualquer ORIGIN_URL que esteja definido para aquele ambiente.

Teste a URL de preview com o Apidog definindo-a como um novo ambiente em seu projeto. Execute sua suíte de testes completa contra ela. Se tudo passar, faça o merge da branch.

git checkout main
git merge feature/products-gateway
git push origin main

O merge aciona o deploy de produção. Em sessenta segundos, a nova versão estará ativa em mais de 300 localidades de edge. A promoção e o rollback são ambos operações de git push; não há uma UI separada.

Passo 8: Gere o portal do desenvolvedor

O portal está hospedado em https://YOUR-PROJECT.developers.zuplo.com e é reconstruído a cada deploy. Ele inclui:

Se sua especificação OpenAPI tiver boas descrições e exemplos, o portal parecerá pronto sem trabalho adicional. Se sua especificação for escassa, este é o momento em que você descobrirá.

Para personalizar, o código-fonte do portal é enviado como um aplicativo Next.js separado que você pode forkar do repositório do portal do desenvolvedor Zuplo no GitHub. A maioria das equipes permanece na versão hospedada.

Passo 9: Teste tudo com o Apidog

Uma vez que seu gateway esteja ativo, a disciplina que evita incidentes de produção é testar todas as rotas, todas as políticas e todos os caminhos de erro. O Apidog torna isso rápido.

O fluxo de trabalho que funciona bem:

  1. Importe a especificação OpenAPI do gateway de https://YOUR-PROJECT.zuplo.app/openapi. O Apidog transforma cada operação em uma requisição que você pode disparar.
  2. Crie ambientes para local, preview e production, cada um com seu próprio base_url e api_key.
  3. Salve no mínimo três requisições por rota: caminho feliz, falha de autenticação e gatilho de limite de taxa. Execute-as como um grupo antes de cada deploy.
  4. Use os cenários de teste automatizados do Apidog para encadear chamadas (criar um produto, listá-lo, excluí-lo) e verificar as formas das respostas.
  5. Gere exemplos de código na linguagem principal de sua equipe e cole-os em seus runbooks.

Se você está migrando do Postman, o guia de teste de API sem Postman detalha a importação. Baixe o Apidog se você ainda não o fez.

Perguntas comuns sobre o uso do Zuplo

Como alterno uma rota entre ambientes sem alterar a especificação?

Use variáveis de ambiente. Defina ORIGIN_URL por ambiente nas Configurações do portal ou em config/.env localmente, e referencie-o como ${env.ORIGIN_URL} dentro das opções do handler. A rota permanece idêntica; apenas a variável muda.

Posso rodar o Zuplo offline?

Sim. npm run dev inicia um gateway local na porta 9000 com o Route Designer local na porta 9100. Políticas personalizadas, validação e limitação de taxa funcionam localmente; a única coisa que requer conexão com a internet é o serviço gerenciado de chave de API, e você pode executar npx zuplo link para usar o serviço em nuvem a partir de sua instância local.

Como faço rollback de um deploy ruim?

Faça git revert do commit de merge e um push. O Zuplo faz o deploy do estado anterior. Não há um botão de "rollback" separado porque o histórico do Git é a fonte da verdade.

O que acontece com as requisições em andamento durante um deploy?

Os deploys são atômicos na edge; as requisições em andamento terminam na versão antiga e as novas requisições atingem a nova versão. Não há janela de inatividade.

Posso usar o Zuplo com gRPC ou WebSockets?

Sim. O urlForwardHandler faz proxy de upgrades WebSocket de forma transparente, e o gRPC é suportado através do handler gRPC. REST e GraphQL são de primeira classe e o caso mais comum.

Como exponho minha API Zuplo para agentes de IA?

Adicione o MCP Server Handler a uma rota, aponte-o para sua especificação OpenAPI e escolha as operações a expor. As mesmas políticas de autenticação e limite de taxa se aplicam às requisições MCP. A documentação do Zuplo MCP Server cobre a configuração.

Quanto custa o gateway em produção?

A camada gratuita cobre 100 mil requisições por mês. O plano Builder adiciona 1 milhão de requisições por $25 por mês, e requisições adicionais custam $100 por 100 mil. O preço Enterprise começa em $1.000 por mês em um contrato anual. Detalhes completos na página de preços do Zuplo.

Conclusão

Agora você tem um gateway Zuplo funcionando com autenticação por chave de API, limitação de taxa por chave, validação de requisições, uma política de saída TypeScript personalizada e um portal do desenvolvedor, tudo sendo implantado via Git para a edge global. O mesmo projeto gerencia ambientes de preview, lançamentos de produção e acesso de agentes de IA via MCP.

A peça que o mantém estável é o loop de testes. Use o Apidog contra cada preview antes de fazer o merge, e você pegará os cabeçalhos de autenticação quebrados, os campos de esquema ausentes e os limites de taxa que foram acidentalmente muito generosos antes que eles sejam enviados. Baixe o Apidog e conecte-o ao seu gateway hoje.

botão

Pratique o design de API no Apidog

Descubra uma forma mais fácil de construir e usar APIs