KEPLIN Docs

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.

O painel Código com a secção APIs, e a visão geral da app com o endereço do endpoint.
O painel Código com a secção APIs, e a visão geral da app com o endereço do endpoint.

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

  1. 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.
  2. 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.
  3. 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).

O modal Nova API — só o nome; a natureza define-se depois, no construtor.
O modal Nova API — só o nome; a natureza define-se depois, no construtor.

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.

O construtor de uma API de pipeline, no separador Construir.
O construtor de uma API de pipeline, no separador Construir.

Identificação

Na secção Identificação defines:

  • OperaçãoQuery — 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.

A secção Argumentos, com um argumento declarado e o valor de teste preenchido.
A secção Argumentos, com um argumento declarado e o valor de teste preenchido.

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:

  1. O ficheiro é guardado no armazenamento escolhido.
  2. No pipeline, o argumento deixa de ser o ficheiro em bruto e passa a ser uma referência com filename, mimeType, size e um token — é isto que um passo Script recebe em input["args"]["nomeDoArg"].
  3. 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

  1. Escolhe o Datasource — uma das bases de dados registadas na app. Sem datasources, o passo mostra o atalho para criar o primeiro.
  2. Escreve a query no editor. Escreve : para autocompletar argumentos; o editor conhece as tabelas e colunas do datasource escolhido e sugere-as enquanto escreves.
  3. 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.

Um passo Query SQL com o datasource escolhido e o editor da query.
Um passo Query SQL com o datasource escolhido e o editor da query.

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:

  1. Escolhe o Método (GET, POST, PUT, PATCH ou DELETE) e preenche o URL — ex.: https://api.exemplo.pt/clientes/:clienteId.
  2. Acrescenta Headers com Adicionar header — por exemplo Authorization com o valor Bearer :token.
  3. 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:

  1. 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.
  2. 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:

  1. Preenche os valores de teste dos argumentos (na secção Argumentos).
  2. 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.
  3. 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.
  4. Se os passos escreveram logs (um script que imprime, por exemplo), aparecem no bloco Logs.

O painel Testar o pipeline (rascunho), com o botão Executar — ainda sem execuções nesta sessão.
O painel Testar o pipeline (rascunho), com o botão Executar — ainda sem execuções nesta sessão.

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).

O separador Docs, com o endpoint e os exemplos prontos a copiar da operação getContactos.
O separador Docs, com o endpoint e os exemplos prontos a copiar da operação getContactos.

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).