Gå til hovedinnhold
Mål

Når du er ferdig med dette kapittelet, skal du være i stand til å finne filene som utgjør GraphQL-skjemaet, i FS-plattform-repoet og forstå hvordan det settes sammen til et ferdig skjema. Du skal også ha fått innsikt i hvordan feature-flagg og objektutvidelser fungerer, og forstår konsekvensene av at hvilken mappe filen du redigerer på, befinner seg i.

Redigere GraphQL-skjemaet

GraphQL-skjemaet ligger i FS-plattform-repoet under /fs-graphql-spec/src/main/resources/schema/. Du kan redigere skjemaet direkte på gitlab.sikt.no, eller via et utviklerverktøy som IntelliJ eller Microsoft Visual Studio Code.

Skjemaet er splittet i flere filer

I /fs-graphql-spec/src/main/resources/schema/ og undermapper vil du finne flere *.graphql-filer. Disse filene blir satt sammen til det ferdige GraphQL-skjemaet som brukes av APIet. schema_prod.graphql danner utgangspunktet sammen med de filene som ligger i common-mappa, og de andre filene blir sett på som tillegg til dette skjemaet.

Feature-flagg bestemmer hvilke deler av skjemaet som er synlig for brukeren

For å støtte gradvis utrulling av funksjonalitet som er under utvikling, har vi laget et system med feature-flagg. Kort fortalt betyr det at funksjonalitet som ikke er i full produksjon ennå, må etterspørres av brukeren for at den skal være synlig. Dette gjelder både ved inspeksjon av skjemaet i Voyager og GraphiQL og ved kall mot APIet. Mer informasjon finner du i den tekniske dokumentasjonen for FS GraphQL API.

Ved utvikling lokalt er feature-flaggene satt til å inkludere experimental og beta. Hvis man ikke ønsker det, f.eks. ved jobbing med beta/prod-setting, kan man fjerne disse ved å redigere application.feature-flags i /fsapi-rest/fsapi-rest/src/main/webapp/META-INF/microprofile-config.properties.

Feature-flagg blir satt automatisk på alt som ligger i features-katalogen

Vi har to feature-flagg som samsvarer med stabilitetsnivåene "eksperimentell" og "beta" i API-kontrakten. I /fs-graphql-spec/src/main/resources/schema/features/ vil du finne én katalog for hvert av disse flaggene. For alle filer som legges i disse katalogene, blir tilsvarende feature-flagg satt automatisk på alle felter, argumenter og enum-verdier.

Du kan lage dine egne feature-flagg

Feature-flaggene beta og experimental er dokumentert offentlig, og ment å kunne brukes av alle autentiserte brukere. I noen tilfeller kan du ha behov for å teste ut ting mer ad hoc, for eksempel i samarbeid med én bestemt kunde, eller du ønsker av andre årsaker ikke at funksjonaliteten skal bli tilgjengelig for enhver med én gang. Dette løser du ved å sette et @feature-direktiv direkte på feltet eller feltene du ønsker skal være flagget, eks. slik:

type StudentVedInstitusjon {
faddergruppe: String @feature(flags:["faddergruppetest"])
}

Nå er det bare brukere som kjenner til faddergruppetest-flagget som kan be om denne funksjonaliteten.

Hvis du vil flagge mange felter samtidig, eller hvis feature-flagget skal leve en stund, kan det være fornuftig å opprette en egen katalog i /fs-graphql-spec/src/main/resources/schema/features/ for flagget. Navnet på flagget vil da bli identisk med navnet på katalogen.

Utvide objekter som finnes i andre filer

I noen tilfeller vil vi ha typer som f.eks. eksisterer i produksjonsdelen av skjemaet, mens vi har felter på disse typene som skal ha feature-flagg. For at det samlede skjemaet skal bli generert riktig, bruker vi det som kalles Object Extensions. Det gjøres slik:

Query-rota ligger i prod-skjemaet:

type Query {
"""Dette feltet er nødvendig for å kunne visualisere et tomt skjema. Den slettes så snart noe har kommet inn i produksjon."""
_intet: Boolean @notGenerated @deprecated
}

Nå vil vi legge til en kant på query-rota i experimental-skjemaet. I experimental-skjemaet definerer vi ikke Query-typen på nytt, men vi legger inn en utvidelse av denne typen slik:

extend type Query {
studenter: StudenterConnection
}

Det genererte experimental-skjemaet vil da inneholde kombinasjonen av disse to:

type Query {
"""Dette feltet er nødvendig for å kunne visualisere et tomt skjema. Den slettes så snart noe har kommet inn i produksjon."""
_intet: Boolean @notGenerated @deprecated
"""Returnerer lister med studenter med forskjellige filtreringsmuligheter"""
studenter(
"""Oppgi hvilken institusjon du vil hente studenter fra"""
eierInstitusjonsnummer: String! @field(name: "INSTITUSJONSNR_EIER"),
"""Liste med fødselsnumre"""
fodselsnummer: [String!] @field(name: "FODSELSNR"),
"""Liste med studentnumre"""
studentnumre: [String!] @field(name: "STUDENTNR_TILDELT")
"""Liste med personløpenumre"""
personlopenumre: [String!] @field(name: "PERSONLOPENR")
"""Liste med Feide-brukernavn"""
feideBruker: [String!] @field(name: "FEIDE_BRUKER"),
first: Int = 100,
after: String,
): QueryStudentVedInstitusjonConnection @connection(for: "StudentVedInstitusjon")
}

Prod-skjemaet blir ikke berørt:

type Query {
"""Dette feltet er nødvendig for å kunne visualisere et tomt skjema. Den slettes så snart noe har kommet inn i produksjon."""
_intet: Boolean @notGenerated @deprecated
}

Nyutvikling skal aldri skje direkte i prod- eller beta-katalogen

Det er ikke meningen at nyutvikling skal gjøres direkte i prod- og beta-katalogene, selv om rene feilrettinger og oppdatering av dokumentasjon selvsagt er tillatt. Når funksjonalitet skal løftes fra eksperimentell til beta til full produksjon, må det gjennom en form for kvalitetssikring som sikrer at den er "klar for beta" og "klar for prod". Det er påbegynt en prosedyre for det her: Endring av API-kontrakt. Denne må tilpasses etterhvert som vi gjør oss erfaringer.