Innhold
1 Komponenter på server
- Gunicorn
- Python WSGI HTTP server. Håndterer forespørsler til selve applikasjonen.
- nginx
- HTTP-/proxyserver som plasseres foran Gunicorn.
HTTP-/proxyserveren nginx settes opp på samme server som Cerebrum kjører på. nginx konfigureres opp med en virtualhost (f.eks. api.cerebrum-inst.uio.no) som har gyldige sertifikater og lytter på port 443.
nginx terminerer SSL-tilkoblingen, og videresender selve forespørselen til Gunicorn sammen med informasjon om klientsertifikatet om et slikt ble brukt ved tilkobling.
Gunicorn trenger ikke installeres for seg selv, det vil være en del av Cerebrum sitt virtualenv.
2 Komponenter i kodeverk
- Flask
- Lite, men kraftig webapplikasjonsrammeverk for Python.
- Flask-RESTful
- Abstraksjoner og verktøy som forenkler utviklingen av REST-API-er i Flask.
- Flask-RESTful-Swagger
- Produserer interaktiv dokumentasjon av API-et basert på modellene og endepunktene/operasjonene vi definerer for Flask-RESTful. Les mer om Swagger.
3 URL-design
3.1 Endepunkter
Adressene til endepunktene i API-et kan minne om et mappehierarki:
/version/collection/resource/subcollection/subresource
- version
- Versjonsnummer, f.eks. v1
- collection
- En samling objekter, f.eks. accounts, groups og persons
- resource
- Identifikatoren til ressurs (enkeltobjekt), f.eks. kontoen olanord eller personen med entitets-ID 34540.
- subcollection
- Relasjonen en ressurs har til andre samlinger, f.eks. kontaktinformasjonen eller gruppemedlemskapene til en bruker.
- subresource
- Identifikatoren til en ressurs i en undersamling, f.eks. et bestemt gruppemedlemskap.
Noen eksempler hvordan adressene kan se ut:
- /v1/accounts
- Liste over alle brukere, evt. filtrert
- /v1/accounts/olanord
- Brukeren olanord
- /v1/accounts/olanord/groups
- Liste over gruppemedlemskapene til olanord, evt. filtrert
- /v1/accounts/olanord/affiliations/88345
- Brukeren olanord sin tilknytning med ID 88345
Oppførselen til disse endepunktene avhenger fullstendig av hvilken HTTP-metode som brukes:
- GET
- Henter ut informasjon
- POST
- Oppretter noe nytt
- PUT
- Oppdaterer noe eksisterende
- PATCH
- Oppdaterer deler av noe eksisterende
- DELETE
- Sletter
Se Use RESTful URLs and actions i Best Practices for Designing a Pragmatic REST API.
3.2 Identifikatorer
Det bør kun eksistere én URL til hver ressurs.
I de tilfellene det finnes et unikt navn på ressursen, bør dette brukes som identifikator. Eksempler på slike ressurser er brukere og grupper.
Om en ressurs mangler et unikt navn, kan man benytte Cerebrums interne entitets-ID. Eksempler på slike ressurser er personer og organisasjonsenheter.
Type | Identifikator |
---|---|
Account | account_name (str) |
Group | group_name (str) |
Person | entity_id (int/long) |
OU | entity_id (int/long) |
Context (spread) | spread (str) |
3.3 Versjonering
Vi benytter oss av blueprint-funksjonaliteten i Flask for å separere ulike versjoner av API-et. Rutene/endepunktene som defineres i api/v1/routes.py har ikke fått hardkodet inn prefikset /v1/, dette legges til når API-et initialiseres, dvs. i api/__init__.py.
Dette gjør at man enklere kan gjenbruke funksjonalitet fra versjon 1 i en eventuell senere versjon.
4 Dokumentasjon
Alle modeller og operasjoner bør dekoreres med henholdsvis @swagger.model og @swagger.operation og fylles med så mye informasjon som mulig. Se Flask-RESTful-Swagger eller eksisterende kildekode for eksempler.
Dokumentasjonen blir automatisk gjort tilgjengelig under /v1/spec.html (interaktiv) og /v1/spec.json (swagger-spec).
5 Autentisering
Man kan kreve autentisering på en operasjon med å dekorere den med @auth.require().
5.1 Typer
API-et støtter tre typer autentisering:
5.1.1 Klientsertifikater
Ved å plassere nginx foran API-et, kan man validere eventuelle klientsertifikater og sende sertifikatets fingeravtrykk videre til API-et gjennom HTTP-headere. Et fingeravtrykk kan knyttes til en brukerkonto i API-ets konfigurasjonsfil.
5.1.2 HTTP Header (API key)
API-et kan lete i bestemte HTTP-headere etter en nøkkel/konstant. Slike nøkler kan knyttes mot brukerkontoer i API-ets konfigurasjonsfil.
5.1.3 HTTP Basic-Auth
Hvis ingen av autentiseringsmetodene nevnt ovenfor har lykkes, kan API-et settes opp til å be nettleseren om et brukernavn og passord. Dette sjekkes opp mot Cerebrums bruker- og passorddata.
6 Autorisasjon/tilgangskontroll
TBD: Wrappe noe rundt BofhdAuth..?
7 Se også
- Awesome REST
- A collaborative list of great resources about RESTful API architecture, development, test, and performance