Designdokument for Cerebrums REST-API

Cerebrum har et REST-API. Hvilke komponenter er dette basert på, og hvordan bør man benytte seg av dem ved videreutvikling av API-et?

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
Av jbr
Publisert 8. des. 2015 15:47