O construtor de APIs
Criar APIs da app como pipelines de passos — SQL, chamadas HTTP e scripts — com argumentos, teste integrado e documentação gerada.
Cada API do Keplin é uma operação GraphQL da app: uma query que lê dados ou uma mutation que os escreve. Os ecrãs da própria app, os relatórios, os workflows e os sistemas externos chamam todos as mesmas APIs — o que defines aqui é o único caminho de entrada e saída de dados da aplicação.
Uma API pode ter uma de duas naturezas:
| Natureza | O que é | Onde se aprofunda |
|---|---|---|
| Pipeline | Uma sequência de passos (Query SQL, Chamada HTTP, Script) que corre por ordem; o resultado do último passo é a resposta. | Esta página |
| Tabela | Um bloco único ligado a uma tabela do modelo de dados, que gera as operações de leitura e escrita (get/add/update/delete) por ti. | A API GraphQL do modelo |
Esta página cobre o construtor em si: criar a API, definir argumentos, montar o pipeline, testar sem gravar e publicar.
Onde vivem as APIs
Dentro de uma app, abre o painel Código na barra lateral. A secção APIs lista as APIs existentes — podes organizá-las em pastas com Nova pasta — e cada uma abre como separador do espaço de trabalho. A app tem também uma página de resumo com a lista completa, o tipo e o estado de cada API, e o endereço onde são servidas.

Nota
No topo da lista vês o endereço da app: todas as operações são servidas
num único endpoint GraphQL, do género /api/graphql/gestao-clientes.
Não há um URL por API — há um campo GraphQL por API.
Criar uma API
- No painel Código, na linha APIs, carrega no botão + (Nova API). O botão Nova API da página de resumo leva-te ao mesmo sítio: o espaço de trabalho da app.
- Dá um Nome. O nome é o campo GraphQL que os clientes vão chamar,
por isso segue a regra: letras, números e underscore, sem começar por
número — por exemplo
getOportunidadesPorConta. - Carrega em Criar API. A API nasce em rascunho e o construtor abre de seguida — é lá que decides a natureza (blocos SQL, HTTP, script ou tabela).

Dica
Se a API vai ser de Tabela, não uses prefixos como get ou add no
nome: o nome é a BASE das operações. Numa API de tabela chamada
contas geram-se getContas, addContas, updateContas e
deleteContas — conforme as acções que activares.
O construtor num relance
O cabeçalho do construtor mostra o nome, um selo com o tipo
(query, mutation ou tabela) e o estado (publicada ou
rascunho). À direita ficam os comandos que valem para a API inteira:
| Comando | O que faz |
|---|---|
| Publicada | Liga/desliga a publicação. Uma API em rascunho só é visível para quem constrói; os clientes externos não a vêem. |
| Pública (sem sessão) | Torna a API acessível sem sessão nem API key — para ecrãs públicos da app. Ver APIs públicas. |
| Gravar | Grava a API tal como está. Gravar é sempre possível com nome e argumentos válidos — trabalho a meio grava-se na mesma. |
Por baixo, o trabalho divide-se em três separadores:
| Separador | Para quê |
|---|---|
| Construir | Identificação, argumentos e o pipeline de passos. |
| Testar | Executar o pipeline em rascunho e experimentar a API como um cliente. |
| Docs | Exemplos prontos a copiar para chamar a API de fora. |

Identificação
Na secção Identificação defines:
- Operação — Query — lê dados ou Mutation — escreve dados. A escolha é semântica e prática: as mutations pedem confirmação antes de cada execução de teste, porque escrevem a sério.
- Nome — o campo GraphQL. Se o nome for inválido, o construtor avisa: "camelCase simples: letras, números e underscore, sem começar por número."
Numa API de Tabela não há escolha de operação — as operações derivam das acções CRUD que activares no bloco Tabela.
Argumentos
A secção Argumentos declara os parâmetros que os clientes passam à API. Cada argumento tem:
| Coluna | O que é |
|---|---|
| Nome | Identificador do argumento (letras, números, underscore; não começa por número). |
| Tipo | Um de: String, Int, Float, Boolean, ID, JSON, Upload. |
| Obrig. | Se o cliente é obrigado a enviar o argumento. |
| Default | Valor usado quando o cliente não envia nada. |
| Valor de teste | Só para o botão Executar do separador Testar — não afecta os clientes. |
Dentro do pipeline, os argumentos ficam disponíveis como :nome nos
passos SQL e HTTP, e como input["args"]["nome"] no passo Script.

Dica
Escreve primeiro o pipeline se preferires: quando usas :umNome num
passo sem o teres declarado, aparece a faixa "Usados no pipeline mas
ainda por declarar:" com um botão por nome — um clique e o argumento
fica criado.
Ficheiros como argumento (tipo Upload)
Um argumento de tipo Upload recebe um ficheiro. Nesse caso a coluna
Default dá lugar à escolha do armazenamento: Da app usa o
armazenamento por omissão; em alternativa escolhe um dos armazenamentos
configurados nas definições da app (secção Armazenamento). Assim, uma
API que recebe facturas e outra que recebe fotografias não têm de guardar
os ficheiros no mesmo sítio.
O que acontece quando a API é chamada com um ficheiro:
- O ficheiro é guardado no armazenamento escolhido.
- No pipeline, o argumento deixa de ser o ficheiro em bruto e passa a
ser uma referência com
filename,mimeType,sizee umtoken— é isto que um passo Script recebe eminput["args"]["nomeDoArg"]. - A app fica com o registo do ficheiro, como qualquer outro ficheiro enviado pelos utilizadores.
Para testar, a coluna de valor de teste transforma-se num selector de ficheiro — escolhe um do teu computador e carrega em Executar.
Atenção
Se a app tem vários armazenamentos e nenhum marcado como por omissão,
uma chamada com Upload sem armazenamento escolhido é recusada — a
plataforma não escolhe um por ti.
De fora, o ficheiro envia-se como variável multipart do pedido GraphQL (o formato standard de upload GraphQL); dentro da plataforma, os ecrãs tratam disso por ti.
O pipeline
A secção Pipeline é onde a API ganha corpo. As regras são simples:
- Os passos correm por ordem; o resultado do último é a resposta da API.
- Cada passo (a partir do segundo) pode receber o resultado do anterior — o selo "recebe o resultado do passo N" lembra-o.
- Nos passos SQL e HTTP, o resultado anterior está em
:prev, e aceita caminhos::prev.id,:prev.0.id. - Adicionas passos com os botões Query SQL, Chamada HTTP e Script; o botão Tabela converte a API na natureza de tabela (e não se combina com os restantes blocos).
Enquanto não houver blocos, a secção sugere o caminho: o default é uma Tabela do modelo; em alternativa, constrói-se um pipeline com os passos descritos a seguir.
Passo Query SQL
- Escolhe o Datasource — uma das bases de dados registadas na app. Sem datasources, o passo mostra o atalho para criar o primeiro.
- Escreve a query no editor. Escreve
:para autocompletar argumentos; o editor conhece as tabelas e colunas do datasource escolhido e sugere-as enquanto escreves. - Se a query devolve uma única linha por natureza (um total, um registo por chave), liga Devolver só a primeira linha — a resposta passa de lista a objecto.
Os valores de :argumento e :prev vão sempre parametrizados para a
base de dados — nunca concatenados no texto da query. Isso protege-te de
injecção de SQL sem esforço nenhum.

Dica
A partir do segundo passo, :prev também aparece no autocompletar —
depois de uma execução de teste, as sugestões incluem os caminhos reais
do resultado anterior (ex.: :prev.0.id). Para transformar listas
grandes entre passos, mete um passo de código no meio.
Passo Chamada HTTP
Para falar com serviços externos:
- Escolhe o Método (GET, POST, PUT, PATCH ou DELETE) e preenche o
URL — ex.:
https://api.exemplo.pt/clientes/:clienteId. - Acrescenta Headers com Adicionar header — por exemplo
Authorizationcom o valorBearer :token. - Nos métodos com corpo, preenche o Body; liga Enviar como JSON para o corpo seguir com o tipo de conteúdo correcto.
:nomeDoArg e :prev são substituídos no URL, headers e body.
Passo Script
O passo Script executa um script da app — a mesma lógica que podes correr à mão ou por agendamento, agora como parte de uma API:
- Escolhe o Script na lista (a lista mostra o nome e a linguagem de cada um; só aparecem scripts activos). Sem scripts, o passo mostra o atalho para criar o primeiro.
- Decide se o passo Recebe o resultado do passo anterior — no primeiro passo do pipeline este interruptor não se aplica.
O contrato com o script é claro: os argumentos da API chegam em
input["args"], o resultado do passo anterior em input["prev"], e o
valor devolvido pela função main(input) segue para o passo seguinte
(ou é a resposta, se for o último passo).
Atenção
Se o script escolhido tem um tempo limite alto, o construtor avisa — os clientes da API ficam à espera esse tempo no pior caso. Pipelines de resposta interactiva merecem scripts rápidos.
Reordenar e remover passos
Cada cartão de passo tem setas para Mover para cima / Mover para baixo e um caixote para Remover passo. Mudar o pipeline invalida o resultado do último teste — volta a Executar para veres resultados frescos.
Testar sem gravar
O separador Testar tem duas ferramentas. A primeira, Testar o pipeline (rascunho), corre o pipeline TAL COMO ESTÁ no construtor, sem gravar:
- Preenche os valores de teste dos argumentos (na secção Argumentos).
- Carrega em Executar. Numa mutation, o construtor pede confirmação — "Executar a mutation agora?" — porque o teste corre a sério contra os datasources e uma mutation faz escritas verdadeiras.
- Lê o resultado: o selo Sucesso/Erro com a duração, a
Resposta completa (respostas muito grandes aparecem truncadas), e
com mais de um passo, o Resultado por passo — cada passo com selo
ok/erro, para veres exactamente onde o pipeline partiu. - Se os passos escreveram logs (um script que imprime, por exemplo), aparecem no bloco Logs.

O return type
O return type é a forma da resposta no schema GraphQL — é ele que diz aos clientes que campos podem seleccionar. O construtor infere-o do resultado real: depois de cada execução vê o bloco Return type (inferido). Se diferir do que está guardado, aparece o aviso "Este return type ainda não está guardado" com o botão Guardar return type — e um ponto âmbar no botão Gravar lembra-te do mesmo.
Nota
Sem nenhuma execução, o separador mostra o Return type actual (o guardado). Executa o pipeline para inferir o return type do resultado real — especialmente depois de mudares o SQL ou o script.
Experimentar como um cliente
A segunda ferramenta do separador Testar é um ambiente GraphQL interactivo apontado ao endpoint da app — escreves operações, tens autocompletar do schema e vês as respostas. Como estás autenticado, os rascunhos também aparecem. O botão Abrir em janela abre o mesmo ambiente num separador do browser. Os detalhes ficam no capítulo seguinte, em A API GraphQL do modelo.
Publicar
O interruptor Publicada controla quem vê a API:
- Rascunho — só quem constrói a vê (nas sessões autenticadas, as operações aparecem marcadas como rascunho). Clientes externos e utilizadores da app não a vêem, nem por listagem do schema.
- Publicada — entra no schema para todos os clientes com acesso.
Para gravar como publicada, a API tem de estar completa. O construtor mostra os bloqueios junto ao cabeçalho — por exemplo "Passo 2: o SQL está vazio." ou, numa API de tabela, "Para gravar como publicada, escolhe a tabela e pelo menos uma acção CRUD." Estes avisos nunca impedem o Gravar em rascunho: impedem apenas a publicação.
Nota
Eliminar uma API publicada tira a operação imediatamente do schema — os clientes que a chamavam passam a receber erro. A plataforma avisa antes: a eliminação é permanente.
A documentação gerada (separador Docs)
O separador Docs responde à pergunta "como chamo isto de fora?". É gerado da versão gravada — grava a API primeiro — e mostra:
- O endpoint (
POST /api/graphql/gestao-clientes), com botão de copiar. - A nota de autenticação: o header
x-api-keyé obrigatório para clientes externos — as keys geram-se em API Keys. Na tab Testar (sessão interna) não é preciso. - Uma entrada por operação da API com quatro blocos prontos a copiar: Query GraphQL, Variables, curl e JavaScript (fetch). Numa API de tabela, aparecem todas as operações activas (get, count, add, update, delete).

Porque não…?
- Porque não consigo publicar? Falta o pipeline estar completo — lê os bloqueios junto ao cabeçalho: cada passo em falta é listado com o número e o motivo.
- Porque é que o Executar me pede confirmação? A API é uma mutation: o teste faz escritas verdadeiras. Confirma que estás a apontar a dados de teste.
- Porque não vejo a minha API nova no ambiente de teste GraphQL? Grava primeiro — o ambiente responde sobre a versão gravada. Os rascunhos gravados aparecem (estás autenticado); para clientes externos, só quando publicares.
- Porque não posso juntar um passo SQL a uma API de Tabela? Uma API Tabela não se combina com outros blocos — remove o bloco Tabela primeiro (ou os passos, no sentido inverso).