Modellens GraphQL-API
Tabell-API:erna och GraphQL-schemat som genereras från datamodellen — CRUD-operationer, filter, sortering, sidindelning, totaler och enums.
Varje app i Keplin serverar ett GraphQL-API på en egen endpoint. Det API:ets schema skrivs inte för hand: det genereras från två källor — de API:er du bygger i byggaren och appens datamodell. Modellens tabeller blir GraphQL-typer med sina fält och relationer; modellens enums blir GraphQL-enums; och ett Tabell-API förvandlar en tabell till fullständiga läs- och skrivoperationer, med filter, sortering och sidindelning, utan att du skriver en rad SQL.
Den här sidan täcker endpointen, Tabell-API:erna och det frågespråk de erbjuder klienterna.
Appens endpoint
Alla operationer i en app serveras på en enda GraphQL-endpoint:
POST /api/graphql/<appens-adress>
I exempelappen, POST /api/graphql/gestao-clientes. Begäran är en JSON med query
och variables, som i vilken GraphQL-tjänst som helst — fliken Dokumentation i
varje API ger dig färdiga exempel att kopiera. När appen är publicerad på en egen
adress svarar samma tjänst också på /api/graphql under den adressen.
Vem som får anropa endpointen:
| Vem som anropar | Hur den autentiserar sig | Vad den ser |
|---|---|---|
| Appens skärmar | Appanvändarens session (automatiskt) | Publicerade API:er |
| Externa system | Headern x-api-key — se API-nycklar |
Publicerade API:er inom nyckelns scope |
| Den som bygger | Session på plattformen | Publicerade API:er OCH utkast (märkta som utkast) |
| Anonyma | Ingenting | Bara publika API:er |
Nota
Appens versioner räknas också: en API-nyckel och anonyma begäranden talar alltid med huvudversionen (eller med den publicerade versionen för den adress som används); den som bygger ser SIN arbetsversion. En nyckel snubblar aldrig över det som en developer är halvvägs in i att ändra.
Skapa ett Tabell-API
- Skapa ett API (Nytt API) med det namn som ska
ligga till grund för operationerna — till exempel
contas. - Tryck på knappen Tabell i fliken Bygg, avsnittet Pipeline. Tabell-blocket upptar hela pipelinen — det kombineras inte med SQL-, HTTP- eller Skript-steg.
- Välj tabellen i väljaren Välj tabell… — tabellerna visas grupperade per datakälla, med sökning på tabell- eller datakällenamn.
- Aktivera Exponerade åtgärder och justera Inkluderade fält (se nedan).
- Spara. För att publicera krävs en vald tabell och minst en aktiv åtgärd.


Nota
Väljaren visar bara tabeller som importerats till datamodellen. Om den är tom: importera tabeller i fliken Modell i en datakälla först.
Exponerade åtgärder
Varje aktiv åtgärd genererar en operation i schemat, med namnet härlett från basen —
för API:et contas:
| Åtgärd | Genererad operation | Vad den gör |
|---|---|---|
| Select | getContas (query) |
Lista med filter, sortering och sidindelning. Den tar med sig countContas, totalen. |
| Insert | addContas (mutation) |
Skapar en rad. |
| Update | updateContas (mutation) |
Uppdaterar en rad via primärnyckeln — partiellt: bara det du skickar ändras. |
| Delete | deleteContas (mutation) |
Tar bort en rad via primärnyckeln och returnerar true. |
Raden Publik åtkomst (utan session) styr, åtgärd för åtgärd, vad de publika skärmarna får anropa — detaljer i publika API:er.
Inkluderade fält
Trädet Inkluderade fält definierar svarets form: avmarkera de fält du inte vill
exponera, och expandera navigationsfälten för att inkludera relaterade
entiteter — rekursivt, som i en visuell GraphQL-editor. I ett API contas gör en
expandering av navigatorn contactos att klienterna kan begära varje kontos
kontakter i samma anrop.

Atenção
Med Insert eller Update aktiva inkluderas tabellens obligatoriska fält alltid (icke-nullbara, utan automatiskt värde) — utan dem skulle det inte gå att skapa giltiga rader. Byggaren visar dem markerade och låsta.
Läsa data: filter, sortering, sidindelning
Listfrågan tar emot fyra argument: where, order, take och skip. Ett
fullständigt exempel i appen Kundhantering:
query {
getContas(
where: { cidade: { eq: "Lisboa" }, estado: { neq: "ARQUIVADA" } }
order: [{ nome: ASC }]
take: 20
skip: 0
) {
id
nome
cidade
contactos {
nome
email
}
}
}
Argumentet where
Varje filtrerbart fält tar emot operatorer beroende på typen:
| Fältets typ | Operatorer |
|---|---|
| Text (och enums) | eq, neq, contains, startsWith, endsWith, gt, gte, lt, lte, in, nin |
Tal (Int, Float) |
eq, neq, gt, gte, lt, lte, in, nin |
Boolean |
eq, neq |
ID |
eq, neq, in, nin |
Och två kombinatorer för sammansatta villkor: and och or, som tar emot listor av
filter.
where: {
or: [
{ cidade: { eq: "Lisboa" } }
{ cidade: { eq: "Porto" } }
]
valorAnual: { gte: 10000 }
}
Nyttiga regler:
eq: nullhittar posterna där fältet är tomt;neq: null, de ifyllda.- Datumintervall: datum som sparas som ISO-text (t.ex.
2026-08-11) sorteras alfabetiskt precis som de sorteras i tiden, och därför räckergt/lt/gte/ltepå text för att filtrera intervall —dataCriacao: { gte: "2026-01-01", lt: "2026-07-01" }. intar emot en lista med värden;ninutesluter den.- Filtrets värden går alltid parametriserade till databasen — ett
containsmed illasinnad text är ingen risk.
Sortera och sidindela
orderär en lista av{ fält: ASC }eller{ fält: DESC }— flera poster sorterar på flera fält, i den ordning de anges.takebegränsar antalet rader (tak på 10 000 per begäran) ochskiphoppar över de första N — tillsammans ger de den klassiska sidindelningen.
Totalen: count
Varje Tabell-API med Select aktivt får också count<Namn>, som returnerar
totala antalet rader för SAMMA where. Det naturliga paret för en sidindelad tabell
är att begära sidan och totalen i en enda operation, med alias:
query {
items: getContas(take: 10, skip: 0) { id nome }
total: countContas
}
Med filter: skicka samma where till båda fälten — totalen räknar exakt de rader
som listan skulle returnera utan sidindelning.
Skriva data
addContastar emot de inkluderade fälten som argument (tabellens obligatoriska fält är obligatoriska i mutationen). I vissa databaser är svaret den skapade raden; i andra,true— API:ets flik Dokumentation visar den exakta formen i ditt fall.updateContastar emot primärnyckeln (obligatorisk) och de övriga fälten som valfria — den uppdaterar bara det du skickar — och returnerar den uppdaterade raden.deleteContastar emot primärnyckeln och returnerartrue.
mutation ($nome: String!, $cidade: String) {
addContas(nome: $nome, cidade: $cidade) {
id
nome
}
}
Nota
Appens behörigheter gäller här, alltid: om appanvändaren bara får se sitt lags
konton returnerar — och räknar — getContas och countContas bara dessa, oavsett
vem som anropar (skärm, rapport eller arbetsflöde).
Enums
En enum exponerar en fast uppsättning värden i GraphQL-schemat — ett kontos status, en affärsmöjlighets fas. De hanteras på sidan API:er, fliken Enums:
- Tryck på Ny enum.
- Ge den ett namn (t.ex.
EstadoConta) och, om det hjälper, en beskrivning. - Lägg till värden med Lägg till värde — varje värde har en identifierare (value) samt en valfri etikett och färg. Färgen och etiketten används av skärmarna; det är value som reser i API:et.
- Spara.


En enum används på två ställen: som typ för ett fält i modellen (fältet tar då bara emot de värdena, och i filtren beter det sig som text) och som typ för ett API:s argument. I schemat ser klienterna enumen med sina värden — testmiljöns autokomplettering föreslår dem.
Atenção
Att ta bort en enum är permanent, och de fält och argument som använde den slutar referera till den. Föredra att redigera värdena framför att ta bort enumen.
Utforska schemat i GraphiQL
Fliken Testa i vilket API som helst innehåller GraphiQL — den interaktiva miljön för appens endpoint. Du skriver operationen till vänster, kör, och ser svaret till höger; autokompletteringen känner hela schemat, Tabell-operationerna inkluderade. Knappen Öppna i fönster ger dig samma miljö i helskärm.

Eftersom du är inloggad på plattformen kör GraphiQL som en klient men ser också utkasten — varje operation som är utkast visas med beskrivningen ”UTKAST” i schemats dokumentation. Och den svarar utifrån din arbetsversion: det du designar är det du testar.
Varför inte…?
- Varför ser jag inte operationen
getContasutifrån? Antingen är API:et ett utkast (publicera det), eller så är åtgärden Select inte aktiv, eller så har din nyckel inte den endpointen i sitt scope. - Varför dyker ett fält inte upp i svaret? Det är inte markerat under Inkluderade fält — klienterna kan bara välja det som API:et inkluderar.
- Varför returnerar
addContasetttruei stället för raden? Det beror på databasen bakom tabellen. När du alltid behöver raden: följ upp med ettgetContasfiltrerat på nyckeln. - Varför ändrades schemat utan att jag rört API:erna? Schemat genereras från modellen: att importera nya kolumner, ändra en enum eller inaktivera en entitet slår igenom i API:et vid nästa anrop.