Gå til hovedinnhold

Kom i gang med Utdanningsregister API

Denne guiden viser hvordan du kommer i gang med Utdanningsregisteret GraphQL API etter at du har fått tilgang via Maskinporten.

Forutsetninger

Du må ha gjennomført Skaffe tilgang og ha et gyldig access token før du kan utføre queries.

Hva er GraphQL?

GraphQL er et spørrespråk for API-er som lar deg:

  • Be om kun de dataene du trenger - ingen over-fetching eller under-fetching
  • Hente relaterte data i én request - unngå flere API-forespørsler
  • Få sterk typing - APIet er selvdokumenterende via introspection

Les mer om GraphQL-konsepter i FS GraphQL-veilederne.

Utforsk API-et i Apollo Studio

Se alle endpoints og feltdefinisjoner i Apollo Studio. Nyttig for å utforske hvilke felt og filtre som er tilgjengelige.

Din første query

La oss hente alle læresteder (universiteter, høyskoler, fagskoler) - en enkel query uten parametere:

query HentAlleLaresteder {
alleLaresteder {
id
dbhInstitusjonskode
erSelvakkrediterende
organisasjon {
id
organisasjonskode
originalnavn
}
type {
kode
navn
beskrivelse
}
}
}

Forklaring:

  • query HentAlleLaresteder - Gir queryen et navn (valgfritt, men anbefalt)
  • alleLaresteder - Query-feltet som returnerer alle læresteder
  • Inni { } spesifiserer du hvilke felt du vil ha i responsen
  • organisasjon { ... } og type { ... } - Henter nested data om organisasjon og lærested-type

Eksempel resultat:

{
"data": {
"alleLaresteder": [
{
"id": "MTAxMDI6MTUw",
"dbhInstitusjonskode": "1260",
"erSelvakkrediterende": true,
"organisasjon": {
"id": "MTAxMDQ6MTUw",
"organisasjonskode": "150",
"originalnavn": "Norges idrettshøgskole"
},
"type": {
"kode": "VITHØGSKOLE",
"navn": "Vitenskapelig høgskole",
"beskrivelse": "Vitenskapelig høgskole er spesialisert høyskole som driver undervisning og forskning eller utviklingsarbeid på universitetsnivå i fag som vanligvis ikke dekkes av de tradisjonelle universitetene."
}
},
{
"id": "MTAxMDI6MTU4",
"dbhInstitusjonskode": "8241",
"erSelvakkrediterende": true,
"organisasjon": {
"id": "MTAxMDQ6MTU4",
"organisasjonskode": "158",
"originalnavn": "Handelshøyskolen BI"
},
"type": {
"kode": "HØGSKOLE",
"navn": "Høyskole",
"beskrivelse": "Høyskole er en type utdanningsinstitusjon som tilbyr høyere utdanning innen bestemte fagområder, eksempelvis profesjonsutdannelser. Det finnes både statlige og private høyskoler."
}
}
]
}
}

Utføre queryen

Med cURL:

curl -X POST https://api.fsweb.no/graphql \
-H "Authorization: Bearer ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-H "Feature-Flags: beta,experimental" \
-d '{
"query": "query HentAlleLaresteder { alleLaresteder { id dbhInstitusjonskode erSelvakkrediterende } }"
}'
Feature Flags påkrevd

API-et krever Feature-Flags: beta,experimental header for alle forespørsler.

Paginering

Mange queries returnerer store datasett og bruker cursor-basert paginering (Relay-stil) for effektiv datahåndtering.

Cursor-basert paginering

Cursor-basert paginering bruker cursors (pekere) for å navigere gjennom resultatsett. En cursor er en streng som peker til et spesifikt element i resultatet.

Om cursors

Cursors er ugjennomsiktige verdier (f.eks. "WzFd" eller "WzEwXQ"). Du skal ikke prøve å tolke eller endre dem - bare bruke dem som pekere til neste/forrige side.

Fordeler:

  • Stabil over tid (selv om data endres)
  • Effektiv for store datasett
  • Støtter forward-only navigering (fremover gjennom datasett)

Grunnleggende paginering

query HentAlleUtdanningsmuligheter {
alleUtdanningsmuligheter(first: 10) {
totalCount
pageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
}
nodes {
id
kode
}
}
}

Resultat:

{
"data": {
"alleUtdanningsmuligheter": {
"totalCount": 637,
"pageInfo": {
"hasNextPage": true,
"hasPreviousPage": false,
"startCursor": "WzFd",
"endCursor": "WzEwXQ"
},
"nodes": [
{ "id": "MTAxNTQ6MQ", "kode": "HFD-KURS" },
{ "id": "MTAxNTQ6Mg", "kode": "HFB-NORS" },
{ "id": "MTAxNTQ6Mw", "kode": "HFB-EST" },
{ "id": "MTAxNTQ6NA", "kode": "HFB-KLAR" },
{ "id": "MTAxNTQ6NQ", "kode": "DRPHILJUR" },
{ "id": "MTAxNTQ6Ng", "kode": "HFB-FRI" },
{ "id": "MTAxNTQ6Nw", "kode": "HF1-NOAS" },
{ "id": "MTAxNTQ6OA", "kode": "HFB-AAS" },
{ "id": "MTAxNTQ6OQ", "kode": "HFCUMAS" },
{ "id": "MTAxNTQ6MTA", "kode": "HFB-KONS" }
]
}
}
}

Forklaring:

  • first: 10 - Ber om de 10 første elementene
  • nodes - Inneholder de 10 elementene som ble hentet
  • hasNextPage: true - Det finnes flere sider
  • endCursor - Bruk denne for å hente neste side

Hente neste side

Bruk endCursor fra forrige respons som after-parameter:

query NesteSide {
alleUtdanningsmuligheter(first: 10, after: "WzEwXQ") {
totalCount
pageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
}
nodes {
id
kode
}
}
}

Dette henter elementene 11-20.

Pagination-parametere

ParameterTypeBeskrivelse
firstIntHent N første elementer
afterStringStart etter denne cursor

Viktige begrensninger

API-begrensninger du må kjenne til

Forward-only paginering API-et støtter kun first og after parametere. Du kan ikke navigere bakover med last eller before.

Maksimal page size: 1000 elementer Backend har en hard grense på 1000 elementer per respons. Hvis du spesifiserer first: 5000, får du kun tilbake maksimalt 1000 elementer.

Default page size Hvis du ikke spesifiserer first, får du maks 100 elementer for queries på Query-rota.

totalCount er begrenset totalCount viser ikke totalt antall i databasen, men antall tilgjengelig fra gjeldende posisjon (max 1000).

Eksempel: Hvis det finnes 3001 utdanningsmuligheter totalt:

  • Side 1: totalCount: 1000 (elementer 1-1000)
  • Side 2: totalCount: 1000 (elementer 1001-2000)
  • Side 3: totalCount: 1000 (elementer 2001-3000)
  • Side 4: totalCount: 1 (element 3001)

For å vite det faktiske totale antallet må du paginere gjennom alle sider til hasNextPage blir false.

Pattern for å hente alle sider

Pseudokode:

1. Første request: first: 100
2. Sjekk pageInfo.hasNextPage
3. Hvis true: gjenta med after: pageInfo.endCursor
4. Fortsett til hasNextPage = false

JavaScript-eksempel:

async function hentAlleUtdanningsmuligheter() {
let allData = [];
let hasNextPage = true;
let cursor = null;

while (hasNextPage) {
const query = `
query ($after: String) {
alleUtdanningsmuligheter(first: 100, after: $after) {
pageInfo {
hasNextPage
endCursor
}
nodes {
id
kode
}
}
}
`;

const response = await fetch('https://api.fsweb.no/graphql', {
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json',
'Feature-Flags': 'beta,experimental'
},
body: JSON.stringify({
query,
variables: { after: cursor }
})
});

const data = await response.json();
const result = data.data.alleUtdanningsmuligheter;

allData = allData.concat(result.nodes);
hasNextPage = result.pageInfo.hasNextPage;
cursor = result.pageInfo.endCursor;

console.log(`Hentet totalt ${allData.length} utdanningsmuligheter`);
}

return allData;
}