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.
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
- Cadastre-se em portal.zuplo.com ou crie um projeto local com
npm create zuplo. - Defina rotas em
config/routes.oas.jsone as encaminhe para sua origem com o URL Forward Handler. - Adicione políticas de entrada (autenticação por chave de API, limitação de taxa, validação de esquema) editando o arquivo de rota ou clicando no Route Designer.
- Escreva lógicas personalizadas como módulos TypeScript em
modules/; o runtime oferece acesso tipado à requisição, contexto e ambiente. - Faça push para sua branch Git vinculada para fazer deploy de um ambiente de preview; faça merge para lançar em produção em mais de 300 locais de edge.
- Teste todas as rotas com o Apidog antes de promover para produção.
- O preço começa gratuito com 100 mil requisições por mês; o plano Builder custa $25 por mês.
Pré-requisitos
Você precisa de três coisas antes de começar:
- Uma conta Zuplo
- Uma API de origem para colocar o gateway na frente. Se você não tiver uma, use
https://echo.zuplo.io, que ecoa o que você envia. - Node.js 18 ou superior se você planeja usar o CLI.
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
- Faça login em portal.zuplo.com.
- Clique em "New Project" (Novo Projeto) e escolha um nome como
acme-gateway. - Escolha "Empty Project" (Projeto Vazio) para que nada seja criado automaticamente.
- 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):
- Vá para Services > API Key Service (Serviços > Serviço de Chave de API) no portal.
- Clique em "Create Consumer" (Criar Consumidor).
- Defina o assunto para um identificador estável como
acme-customer-1. - Adicione o e-mail de quem deve gerenciar a chave.
- 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:
- Uma página por rota, com o esquema, descrição e um console para testar.
- Exemplos de código em cURL, JavaScript, Python, Go e alguns outros.
- Emissão de chave de API self-service para qualquer visitante que se cadastrar.
- Controles de branding no portal em Developer Portal > Settings (Portal do Desenvolvedor > Configurações).
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:
- 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. - Crie ambientes para
local,previeweproduction, cada um com seu própriobase_urleapi_key. - 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.
- 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.
- 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.
