SlideShare a Scribd company logo
API Design
7 Kuolemansyntiä
Miksi API design?
• SOAP ja REST rajapintoja voidaan nykyään tehdä hyvin helposti: peruskoodaaja voi katsoa
viiden minuutin tutoriaalin ja tehdä APIn
• Rajapintoja voi jopa generoida, esim. valmiin domain modelin pohjalta, kannan pohjalta, jne
• Esim. Spring Data, JHipster, jne
• Rajapintojen toteutuksessa on paljon joustovaraa: Suuressa tiimissä voi jokainen tehdä eri
tavalla
• Monet rajapinnat tehdään hetken tarpeeseen, miettimättä elinkaarta
• Rajapintojen tehtailu ilman suurempaa suunnitelmaa johtaa rönsyilevään viidakkoon jota on
vaikea ylläpitää tai käyttää
• Tässä esityksessä keskitytään moderneihin REST rajapintoihin, jotta saadaan konkretiaa
aikaan – monet periaatteet soveltuvat kuitenkin muihinkin tekniikoihin
Millainen on hyvä API?
import java.util.concurrent.atomic.AtomicLong;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class GreetingController {
private static final String template = "Hello, %s!";
private final AtomicLong counter = new AtomicLong();
@RequestMapping("/greeting")
public Greeting greeting(
@RequestParam(value="name", defaultValue="World") String name) {
return new Greeting(counter.incrementAndGet(),
String.format(template, name));
}
}
XML vai JSON?
Lähde: https://trends.google.com/trends/explore?date=all&q=xml%20api,json%20api
Synti 1: Epäjohdonmukaisuus
GET /user_messages
GET /userAccount
POST /users/deleteUser
POST /address?delete
Epäjohdonmukaisuus
API operaatioiden välillä url käytännöt vaihtelevat, paluuarvokäytännöt vaihtelevat,
parametrikäytännöt vaihtelevat, sen mukaan kuka on ko palvelun toteuttanut
• HTTP status koodien käyttö vaihtelee ilman johdonmukaisuutta, esim. aina 200, tai sitten
erikseen 201/202/204, jne
• Palauttaako PUT operaatio linkin, id:n, objektin, vai ei mitään? Entäpä POST?
• Oikeasti ei mitään väliä onko Camelcase vai Snake case, kunhan se on johdonmukaisesti
sama
• Käytetäänkö wrapper objekteja (hyi ei!) vai paljasta dataa? Miten käsitellään sivutus?
Yksinkertaisia korjauksia
”Kun teet syntiä, ole edes johdonmukainen”
• Hyvät käytännöt, kuten pariohjelmointi, peer review, team review
• Mikään nyky API standardeista ei ole kaikenkattava, sovitaan yhdessä tiimin kesken
yksityiskohdista
• Tietysti hyvä käyttää vartti siihen että katsoo mitä maailmalla tehdään
• Jos on epävarmaa mikä on oikein, poimitaan parhaiten toimiva/vähiten haitallinen tapa
käytännöksi
• Laajennetaan myös tiimien välille, jotta myös API:en välillä on johdonmukaisuutta
Synti 2: Virheiden käsittelyn virheet
HTTP 200
content-type: application/json; charset=UTF-8
date: Wed, 11 Apr 2018 06:02:32 GMT
{"error": {"message":”Infernal server error"}}
Virheiden käsittelyn virheet
• Palvelun uumenissa menee jotain pieleen, mutta se palauttaa 200 OK HTTP koodin, ja
virhe löytyy vastauspaketin uumenista – tekstinä
• Tai päinvastoin, rajapinta palauttaa vain HTTP statuskoodin, muttei mitään tarkempaa
selitystä käyttäjän suuntaan mitä pitäisi tehdä
• Rajapinta palauttaa kaikissa tilanteissa saman virhekoodin, ilman selityksiä, oli vika sitten
syötteissä tai taustatietokannoissa
• Sovellus kutsuu muita palveluita, jotka voivat myös epäonnistua, ja piilottaa niiden
alkuperäiset virheet käsittelemällä virheet uudestaan
• Ei aina törkein synti, mutta useimmiten
Yksinkertaisia korjauksia
• Signaloi nyt edes virhe ja onnistuminen eri virhekoodilla – tämä taso edellyttää että osaat
ainakin kaksi HTTP koodia – 200 ja 500.
• Virheet voi jakaa kahteen kategoriaan: Kutsuja möhli, tai API möhli. Tästä saat käyttöön
koodit 200 (OK), 400 (Bad request), 500 (Internal server error)
• Jos haluat, tästä voi alkaa hifistelemään lisäämällä 401, 403, 201, 204, 404, 405, 409, 503..
• Pidä huolta että virheilmoituksen mukana palautetaan jotain sopivan käyttökelpoista. Jos
menee liian rönsyileväksi, voi myös toimittaa linkin dokumentaatioon/käyttöoppaaseen
jossa avataan lisää
• Kun sovellus palauttaa johdonmukaiset HTTP koodit, myös sen päällä olevat kerrokset
toimivat paremmin – ei tarvitse parsia tekstistä mikä meni pieleen, ja arvailla
• Masterclass: Palauta virheen mukana tiketti/request id joka viittaa logeista löytyvään
tarkempaan virheeseen
Nojaa HTTP statuskoodeihin
• HTTP 2xx
• Kaikki hyvin
• HTTP 3xx
• Kohde on jossain muualla, seuraa linkkejä
• HTTP 4xx
• Jotain meni pieleen asiakaspäässä
• HTTP 5xx
• Jotain meni pieleen palvelimen uumenissa
Jos pakissasi on jo 200, 201, 204, 304, 400, 401, 403, 404, ja 500,
johdonmukaisesti käytettynä, se on hyvä alku
Synti 3: Verbejä URL osoitteissa (REST)
POST addNewProduct
POST /updateProduct
POST /deleteProduct
POST /deleteAllProducts
GET /getAllProducts
POST /publishProduct
POST /publishAllProducts
POST /unpublishProduct
URLit ovat resursseja, HTTP metodit verbejä
POST /customers
GET /customers
GET /customers/1
PUT /customers/1
DELETE /customers/1
• Mitkä näistä ovat idempotentteja? Mitä hittoa on idempotentti?
Mitä merkitystä sillä on?
• Mitä tekee TRACE, OPTIONS ja PATCH?
No tuo oli vielä helppoa, entäs…
• Tilisiirto tililtä 1 tilille 2?
• Eeentäs aliresurssit? Tilin 1 tapahtumat? Käyttäjän 1 tilit?
Merkitse käyttäjän 1 tili 4 lopetetuksi?
• Ja mites haut nimellä, villikortilla, rajaukset päivämäärällä,
• Entäs muut verbit kuin create, read, update, delete? Esim.
arkistoi?
POST /api/transactions
GET /api/accounts/1/events
DELETE /api/users/1/accounts/4
GET /api/accounts?created_before=2019-01-30
GET /api/accounts?page=5&sort=created
Synti 4: Puuttuva/manuaalinen dokumentaatio
Miten tämän API:n kanssa pääsee edes alkuun?
Mitä tämä API palauttaa?
Puuttuva/Manuaalinen dokumentointi
• Manuaalinen dokumentaatio pakkaa laahaamaan aina jäljessä toteutuksesta. Se on myös
työlästä, ja virhealtista, koska on vaikea todentaa yhteyksiä sanallisen dokumentaation ja
koodin välillä.
• Manuaalinen dokumentaatio on parhaimmillaan hyvin korkeatasoisessa dokumentaatiossa
jossa totuudet eivät tyypillisesti muutu niin herkästi. Matalammilla tasoilla se on kallista,
epäkäytännöllistä, harhaanjohtavaa, ja pelkistetysti sulaa hulluutta.
Yksinkertaisia korjauksia
• Generoi käyttäjän rajapintadokumentaatio koodin pohjalta, automaattisesti, julkaise ne
haluttuun paikkaan ja muotoon
• Ymmärrettävät resurssinimet, parametrinimet, jne
• Lisädokumentaatio esim. annotaatioilla tai muilla loitsuilla suoraan koodiin
• Hyviä työkaluja esim. JavaDoc, Swagger, SpringFox
• Voidaan ajatella myös testejä osana kehittäjädokumentaatiota, jos ne on kirjoitettu hyvin
siinä mielessä
• Voidaan myös tehdä contract-first periaatteella, jolloin esim. swagger kuvaus toimii
yhteisenä sopimuksena
• Käyttöoppaat ja korkean tason arkkitehtuurikuvat on hyvä tehdä erikseen, loput
generoidaan
API Design: 7 kuolemansyntiä
Synti 5: Puuttuva/manuaalinen testaus
Uusi versio, taas hajalla
Manuaalinen testaus
• Manuaalinen testaus on aluksi nopeampaa kuin testien kirjoittaminen – mutta sen
kuormitus kasvaa kun testattavan rajapinnan ja toteutuksen koko kasvaa
• Se mikä oli alussa nopeaa muuttuu raskaaksi ja aina vain hitaammaksi, riski sille että jotain
unohdetaan testata, tai testataan väärin kasvaa, tieto siitä miten rajapinnan ylipäätään piti
toimia jää manuaalisen dokumentaation varaan
• Tässä ympäristössä tuska ja ahdistus kasvaa kasvamistaan
Yksinkertaisia korjauksia
• Aloita testaaminen HETI
• Kirjoita ensimmäinen testi ennen kuin toteutus tekee mitään, aja se, ja totea sen
epäonnistuvan. Lisää toteutusta, lisää testiä, jne. Refaktoroi.
• Hyvä testi jää spesifikaatioksi tuleville kehittäjille/tiimeille siitä miten rajapinnan odotetaan
toimivan, ja toimii apuna regressiotestauksessa kun myöhemmin tehdään muutoksia
• Jos testin halutaan toimivan osana dokumentaatiota, se tulee kirjoittaa myös
dokumentaatiomielessä – ei siis testProducts, vaan ’adding a new product should succeed
when parameters are valid’
• Välineitä: curl, SoapUI, RestAssured, Spock, Fiddler
• Kuormitustestauksen automatisointi: Gatling, JMeter
Synti 6: Tietoturvan laiminlyöminen
GET /prices?query=’;DELETE%20FROM%20prices;--’
Tietoturvan laiminlyöminen
• Pahin synti: Ei ollenkaan autentikaatiota, ei edes API Key
• Tietoturvaa laiminlyödään tyypillisesti OWASP TOP 10 haavoittuvuuksissa, jotka ovat
vaikeammin testattavissa/kontrolloitavissa
• Spesifisempiä osa-alueita mm.
• Security Misconfiguration
• SQL Injection
• DDOS hyökkäykset
• Resurssien suojaus, pääseekö parametreja varioimalla tai fuzz testaamalla tekemään
enemmän kuin pitäisi?
API Design: 7 kuolemansyntiä
Yksinkertaisia korjauksia
• Ei niitä ole, tietoturva on usein alue jossa ei yleensä koeta olevan
rahaa/aikaa tehdä asioita kunnolla/loppuun asti
• Lisää haastetta tulee siitä että testaus ei ole
helppoa/suoraviivaista
• Tietoturvan suhteen ajattelu on usein: Tehdään sitten jotain kun
jotain tapahtuu
No, jotain muita korjauksia?
• SSL ihan kaikkialla aina koko ajan
• Heti alusta alkaen aseta rajoitus kutsuille joita yksi access token/käyttäjä voi tehdä aikayksikössä, esim.
1000/pv – tämä suojaa monelta – tee siitä kuitenkin token kohtainen helposti säädettävä arvo
• Validoi kaikki syötteet, validoi pääsy resursseihin suhteessa käyttäjän oikeuksiin, aina
• Allokoidaan tietoturvaan yksinkertaisesti enemmän rahaa ja aikaa, testaus edellä
• Pidetään huoli että kehittäjillä on ainakin OWASP TOP 10 periaatteet tuoreessa mielessä, ja
pariohjelmoinnissa/katselmoinnissa kiinnitetään näihin huomiota
• Testausta voidaan osin automatisoida, osaksi prosessia, esim. OWASP ZAP Proxy
• Tarvittaessa auditointi/katselmointi, penetraatiotestaus/hackathon tapahtuma, bug bounty
• Fiksu monitorointi paljastaa aikaisin hyökkäysyrityksiä, toistuvia pommituksia voidaan tunnistaa ja
hidastaa
• DDOS hyökkäyksiin ei ole helppoja keinoja, mutta user tokenit, fiksut reitittimet ja palomuurit,
skaalautuva kapasiteetti auttavat
• Pilvestä saa kaikkea tätä helpommin, jos on valmis maksamaan
• Uutuutena myös GDPR tietosuoja-asioiden huomioiminen koko elinkaaren ajan, mm. testidata
Synti 7: Vikasietoisuuden laiminlyönti
Koko ajan hajalla
Monitoroinnin ja seurannan laiminlyönti
• Missä ja miten näkyy kun sovellus ei toimi? Jos vastaus on, että asiakaspalveluun alkaa
tulemaan loppukäyttäjiltä soittoja, vastaus on väärä.
• Miten pitkään kestää toipuminen? Ja yleensä virheen havaitseminen siitä kun se tapahtuu?
Voiko ongelmia ennustaa?
• Saadaanko kiinni hyökkäysyrityksiä? Pystytäänkö niitä blokkaamaan ja toipumaan niistä?
Vikasietoisuuden unohtaminen
• Kun palvelua pyöritetään tarpeeksi pitkään, kaikenlaista tapahtuu
• Levy hajoaa, tietokanta hajoaa, verkkoyhteys sisäverkossa katkeaa, verkkoyhteys ulkoverkossa
katkeaa, sertifikaatit vanhenevat vahingossa, rajapintaan kohdistuu DDOS hyökkäys
• Osaan näistä vastauksen pitäisi olla prosessi ja ylläpito. Mutta osaa on vaikeaa nähdä
edeltä. Silloin pitäisi olla tiedossa sovelluksen haluttu palvelutaso, ja vikasietoisuus.
• Pari kysymystä:
• Miten pitkään sovellus saa olla maissa?
• Miten pitkältä ajalta voidaan menettää dataa?
• Miten nopeasti sovellus pitää saada toipumaan täydellisessä katastrofissa?
Muita syntejä
• Strategian puute – kuka APIa käyttää, mikä on sen elinkaari, ja rooli?
• Elinkaaresta, versioiden hallinnasta, muutosten tiedottamisesta on jo puhuttu aiemmin,
kuitenkin tärkeää! Laiminlyönnit näillä alueilla näkyvät tuskana
• Muutetaanko API ilman varoitusta vai jääkö se ennalleen, ja uusi löytyy osoitteessa
/api/v2/accounts ?
• Vaihtelevat käytännöt jopa saman API:n sisällä!
• HATEOAS? VAI HATE HATEOAS?
• Ei sivutusta, /all palauttaa ennen pitkää miljoonia tietueita
• Microservices helvetti!
• Jouston puute rajapinnoissa
• Liian vaikea käyttää, toimii epävarmasti
Oletko synnintekijä?
Oletko synnintekijä?
Ei se mitään! Useimmat synnit on onneksi
sovitettavissa
• REST ei kuitenkaan ole uskonto, vaan työväline – on hyvä ensin varmistaa että tuntee sen
hyvin, pro-tasolla voidaan sitten harkiten rikkoa sääntöjä – kunhan synti on johdonmukaista, ja
tiimi ja API käyttäjät ymmärtävät
• Eli, aivan ensiksi, avaa muutama nettiresurssi API Design aiheesta, ja pari tuntia aikaa.
Perehdy, opi, haasta.
• Jos REST hankaa vastaan, ei hätää. Se on hyvä paketti mutta ei sovi joka käyttöön ja tuskin on
rajapintojen viimeinen totuus. Aina tulee uutta ja vaihtoehtoista, jos se ei toimi, vaihda se.
• Aika paljon auttaa hyvät kehityskäytännöt, kuten peer review, team review, jne, jossa voidaan
keskustella yksityiskohdista ja yhtenäistää niitä
• Usein projekteissa saattaa olla päinvastoin: Kopioidaan jonkun tekemiä huonoja tapoja
miettimättä niitä, ja ne jäävät käytössä oleviksi antipatterneiksi
• Yhtälailla kannattaa aina välillä kurkata miten muut tekevät rajapintoja oman kuplan ulkopuolella
– erinomainen tilaisuus on myös aina kun tiimiin tulee ulkopuolelta tuoreita silmiä!
Yhteenveto
• Luota/Nojaa vahvasti HTTP protokollaan. Se on yksinkertainen robusti protokolla, jossa on
keinoja jo varsin pitkälle. Tämä koskee eritoten REST rajapintoja.
• Virhekäsittely? HTTP status/virhekoodit. Verbit? HTTP verbit GET, POST, PUT, DELETE.
Suojausmekanismit? HTTPS, ja headerit. Tilasiirtymät? Linkkejä pitkin.
• Tunne teknologiasi. Ei ole ideana tehdä rajapintoja kopioiden viiden minuutin tutoriaaleja ja
kopioiden samoja virheitä, tai mallia joka ei skaalaudu oikeaan käyttöön isommassa
tiimissä. Käytä vartti ja lue muutamasta lähteestä lisää, etenkin alkuperäislähteistä.
• Tiedätkö mikä ero on PUT ja POST välillä? Mitä rajapinta palauttaa kun ei palauteta sisältöä? Mitä
palautetaan PUT metodissa? Entä POST?
• Normaalit kujeet, testaa aikaisin, testaa jatkuvasti, syö omaa koiranruokaasi (yuk), rakenna
se kuin sen käyttäjä olisi psykopaatti joka tuntee osoitteesi, jne
Kiitoksia!
ARTO SANTALA
Software Architect
050 5747452
arto.santala@solita.fi
API Design: 7 kuolemansyntiä

More Related Content

PDF
Store App -kehityksen aloittaminen
PDF
Vincit Teatime 2015 - Niko Kurtti: Case Shopify: SaaS:n testaaminen, mihin un...
PPT
WOA: Web APIt
PDF
Vähemmän ja nopeammin – Välimuistivinkit WordPress-kehittäjille
PPTX
Testaus 2014 -seminaari. Pauli Kauppila, Secrays Oy. Mitä jokaisen testaajan ...
PDF
Kyberrikos 2018 - verkkokaupan kyberriskit ja niihin varautuminen
PPTX
W3 School Selenium 4.2.2013 @ W3 Group Finland, Kerava
PDF
Palvelujen ohjelmointi JavaScriptillä: Node.js ja TypeScript
Store App -kehityksen aloittaminen
Vincit Teatime 2015 - Niko Kurtti: Case Shopify: SaaS:n testaaminen, mihin un...
WOA: Web APIt
Vähemmän ja nopeammin – Välimuistivinkit WordPress-kehittäjille
Testaus 2014 -seminaari. Pauli Kauppila, Secrays Oy. Mitä jokaisen testaajan ...
Kyberrikos 2018 - verkkokaupan kyberriskit ja niihin varautuminen
W3 School Selenium 4.2.2013 @ W3 Group Finland, Kerava
Palvelujen ohjelmointi JavaScriptillä: Node.js ja TypeScript

Similar to API Design: 7 kuolemansyntiä (20)

PDF
Sovellusvirtualisointi - Mitä missä milloin 2015
PDF
JavaScript Frameworkit, jotka kannattaa tuntea
PPTX
Syvemmälle javaan
PDF
Windows 8 yrityksen työasemana
PDF
Mihin robotit hajoavat?
PPTX
Oulu clojure-meetup-20181113
PDF
Vincit Teatime 2015.2 - Aleksi Häkli: SaaSiin pa(i)nostusta
PPTX
Azure JKL Keynote 9.11.2017
PPT
Mainostoimisto Kanava.to – Webortaasi2013
PPT
Liferay Road Show Sosiaali- ja terveysministeriö
PDF
Pragmatic Agile - Aamiaistilaisuus
PDF
Java - analysointityökaluja
PDF
Scrumin nykytila ja kehitys
PDF
Quick Boot A Guide For Embedded Firmware Developers 2nd Edition 2nd Edition P...
PDF
Vincit Teatime 2015 - Heikki Salo: Case ZenRobotics: JavaScriptin äärirajoilla
PDF
Survey of Operating Systems 5th Edition Holcombe Solutions Manual
PDF
Survey of Operating Systems 5th Edition Holcombe Solutions Manual
PPTX
Net ohjelmointi kertaus
PDF
AgileJKL Meetup 2016 - Antti Vartiainen
PPTX
EPiServer7-MVC
Sovellusvirtualisointi - Mitä missä milloin 2015
JavaScript Frameworkit, jotka kannattaa tuntea
Syvemmälle javaan
Windows 8 yrityksen työasemana
Mihin robotit hajoavat?
Oulu clojure-meetup-20181113
Vincit Teatime 2015.2 - Aleksi Häkli: SaaSiin pa(i)nostusta
Azure JKL Keynote 9.11.2017
Mainostoimisto Kanava.to – Webortaasi2013
Liferay Road Show Sosiaali- ja terveysministeriö
Pragmatic Agile - Aamiaistilaisuus
Java - analysointityökaluja
Scrumin nykytila ja kehitys
Quick Boot A Guide For Embedded Firmware Developers 2nd Edition 2nd Edition P...
Vincit Teatime 2015 - Heikki Salo: Case ZenRobotics: JavaScriptin äärirajoilla
Survey of Operating Systems 5th Edition Holcombe Solutions Manual
Survey of Operating Systems 5th Edition Holcombe Solutions Manual
Net ohjelmointi kertaus
AgileJKL Meetup 2016 - Antti Vartiainen
EPiServer7-MVC
Ad

More from Arto Santala (9)

PPTX
Your Brain on Java
PPTX
Java On Speed
PPTX
Migrating to Java 11
PPTX
Leaner microservices with Java 10
PPTX
Automate Everything! (No stress development/Tallinn)
PPTX
Solita /dev/cloud kickstart
PPTX
Kontit pomppimaan3
PPTX
Java9 moduulit jigsaw
PPTX
JavaOne 2016 short highlights
Your Brain on Java
Java On Speed
Migrating to Java 11
Leaner microservices with Java 10
Automate Everything! (No stress development/Tallinn)
Solita /dev/cloud kickstart
Kontit pomppimaan3
Java9 moduulit jigsaw
JavaOne 2016 short highlights
Ad

API Design: 7 kuolemansyntiä

  • 2. Miksi API design? • SOAP ja REST rajapintoja voidaan nykyään tehdä hyvin helposti: peruskoodaaja voi katsoa viiden minuutin tutoriaalin ja tehdä APIn • Rajapintoja voi jopa generoida, esim. valmiin domain modelin pohjalta, kannan pohjalta, jne • Esim. Spring Data, JHipster, jne • Rajapintojen toteutuksessa on paljon joustovaraa: Suuressa tiimissä voi jokainen tehdä eri tavalla • Monet rajapinnat tehdään hetken tarpeeseen, miettimättä elinkaarta • Rajapintojen tehtailu ilman suurempaa suunnitelmaa johtaa rönsyilevään viidakkoon jota on vaikea ylläpitää tai käyttää • Tässä esityksessä keskitytään moderneihin REST rajapintoihin, jotta saadaan konkretiaa aikaan – monet periaatteet soveltuvat kuitenkin muihinkin tekniikoihin
  • 4. import java.util.concurrent.atomic.AtomicLong; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class GreetingController { private static final String template = "Hello, %s!"; private final AtomicLong counter = new AtomicLong(); @RequestMapping("/greeting") public Greeting greeting( @RequestParam(value="name", defaultValue="World") String name) { return new Greeting(counter.incrementAndGet(), String.format(template, name)); } }
  • 5. XML vai JSON? Lähde: https://trends.google.com/trends/explore?date=all&q=xml%20api,json%20api
  • 6. Synti 1: Epäjohdonmukaisuus GET /user_messages GET /userAccount POST /users/deleteUser POST /address?delete
  • 7. Epäjohdonmukaisuus API operaatioiden välillä url käytännöt vaihtelevat, paluuarvokäytännöt vaihtelevat, parametrikäytännöt vaihtelevat, sen mukaan kuka on ko palvelun toteuttanut • HTTP status koodien käyttö vaihtelee ilman johdonmukaisuutta, esim. aina 200, tai sitten erikseen 201/202/204, jne • Palauttaako PUT operaatio linkin, id:n, objektin, vai ei mitään? Entäpä POST? • Oikeasti ei mitään väliä onko Camelcase vai Snake case, kunhan se on johdonmukaisesti sama • Käytetäänkö wrapper objekteja (hyi ei!) vai paljasta dataa? Miten käsitellään sivutus?
  • 8. Yksinkertaisia korjauksia ”Kun teet syntiä, ole edes johdonmukainen” • Hyvät käytännöt, kuten pariohjelmointi, peer review, team review • Mikään nyky API standardeista ei ole kaikenkattava, sovitaan yhdessä tiimin kesken yksityiskohdista • Tietysti hyvä käyttää vartti siihen että katsoo mitä maailmalla tehdään • Jos on epävarmaa mikä on oikein, poimitaan parhaiten toimiva/vähiten haitallinen tapa käytännöksi • Laajennetaan myös tiimien välille, jotta myös API:en välillä on johdonmukaisuutta
  • 9. Synti 2: Virheiden käsittelyn virheet HTTP 200 content-type: application/json; charset=UTF-8 date: Wed, 11 Apr 2018 06:02:32 GMT {"error": {"message":”Infernal server error"}}
  • 10. Virheiden käsittelyn virheet • Palvelun uumenissa menee jotain pieleen, mutta se palauttaa 200 OK HTTP koodin, ja virhe löytyy vastauspaketin uumenista – tekstinä • Tai päinvastoin, rajapinta palauttaa vain HTTP statuskoodin, muttei mitään tarkempaa selitystä käyttäjän suuntaan mitä pitäisi tehdä • Rajapinta palauttaa kaikissa tilanteissa saman virhekoodin, ilman selityksiä, oli vika sitten syötteissä tai taustatietokannoissa • Sovellus kutsuu muita palveluita, jotka voivat myös epäonnistua, ja piilottaa niiden alkuperäiset virheet käsittelemällä virheet uudestaan • Ei aina törkein synti, mutta useimmiten
  • 11. Yksinkertaisia korjauksia • Signaloi nyt edes virhe ja onnistuminen eri virhekoodilla – tämä taso edellyttää että osaat ainakin kaksi HTTP koodia – 200 ja 500. • Virheet voi jakaa kahteen kategoriaan: Kutsuja möhli, tai API möhli. Tästä saat käyttöön koodit 200 (OK), 400 (Bad request), 500 (Internal server error) • Jos haluat, tästä voi alkaa hifistelemään lisäämällä 401, 403, 201, 204, 404, 405, 409, 503.. • Pidä huolta että virheilmoituksen mukana palautetaan jotain sopivan käyttökelpoista. Jos menee liian rönsyileväksi, voi myös toimittaa linkin dokumentaatioon/käyttöoppaaseen jossa avataan lisää • Kun sovellus palauttaa johdonmukaiset HTTP koodit, myös sen päällä olevat kerrokset toimivat paremmin – ei tarvitse parsia tekstistä mikä meni pieleen, ja arvailla • Masterclass: Palauta virheen mukana tiketti/request id joka viittaa logeista löytyvään tarkempaan virheeseen
  • 12. Nojaa HTTP statuskoodeihin • HTTP 2xx • Kaikki hyvin • HTTP 3xx • Kohde on jossain muualla, seuraa linkkejä • HTTP 4xx • Jotain meni pieleen asiakaspäässä • HTTP 5xx • Jotain meni pieleen palvelimen uumenissa Jos pakissasi on jo 200, 201, 204, 304, 400, 401, 403, 404, ja 500, johdonmukaisesti käytettynä, se on hyvä alku
  • 13. Synti 3: Verbejä URL osoitteissa (REST) POST addNewProduct POST /updateProduct POST /deleteProduct POST /deleteAllProducts GET /getAllProducts POST /publishProduct POST /publishAllProducts POST /unpublishProduct
  • 14. URLit ovat resursseja, HTTP metodit verbejä POST /customers GET /customers GET /customers/1 PUT /customers/1 DELETE /customers/1 • Mitkä näistä ovat idempotentteja? Mitä hittoa on idempotentti? Mitä merkitystä sillä on? • Mitä tekee TRACE, OPTIONS ja PATCH?
  • 15. No tuo oli vielä helppoa, entäs… • Tilisiirto tililtä 1 tilille 2? • Eeentäs aliresurssit? Tilin 1 tapahtumat? Käyttäjän 1 tilit? Merkitse käyttäjän 1 tili 4 lopetetuksi? • Ja mites haut nimellä, villikortilla, rajaukset päivämäärällä, • Entäs muut verbit kuin create, read, update, delete? Esim. arkistoi?
  • 16. POST /api/transactions GET /api/accounts/1/events DELETE /api/users/1/accounts/4 GET /api/accounts?created_before=2019-01-30 GET /api/accounts?page=5&sort=created
  • 17. Synti 4: Puuttuva/manuaalinen dokumentaatio Miten tämän API:n kanssa pääsee edes alkuun? Mitä tämä API palauttaa?
  • 18. Puuttuva/Manuaalinen dokumentointi • Manuaalinen dokumentaatio pakkaa laahaamaan aina jäljessä toteutuksesta. Se on myös työlästä, ja virhealtista, koska on vaikea todentaa yhteyksiä sanallisen dokumentaation ja koodin välillä. • Manuaalinen dokumentaatio on parhaimmillaan hyvin korkeatasoisessa dokumentaatiossa jossa totuudet eivät tyypillisesti muutu niin herkästi. Matalammilla tasoilla se on kallista, epäkäytännöllistä, harhaanjohtavaa, ja pelkistetysti sulaa hulluutta.
  • 19. Yksinkertaisia korjauksia • Generoi käyttäjän rajapintadokumentaatio koodin pohjalta, automaattisesti, julkaise ne haluttuun paikkaan ja muotoon • Ymmärrettävät resurssinimet, parametrinimet, jne • Lisädokumentaatio esim. annotaatioilla tai muilla loitsuilla suoraan koodiin • Hyviä työkaluja esim. JavaDoc, Swagger, SpringFox • Voidaan ajatella myös testejä osana kehittäjädokumentaatiota, jos ne on kirjoitettu hyvin siinä mielessä • Voidaan myös tehdä contract-first periaatteella, jolloin esim. swagger kuvaus toimii yhteisenä sopimuksena • Käyttöoppaat ja korkean tason arkkitehtuurikuvat on hyvä tehdä erikseen, loput generoidaan
  • 21. Synti 5: Puuttuva/manuaalinen testaus Uusi versio, taas hajalla
  • 22. Manuaalinen testaus • Manuaalinen testaus on aluksi nopeampaa kuin testien kirjoittaminen – mutta sen kuormitus kasvaa kun testattavan rajapinnan ja toteutuksen koko kasvaa • Se mikä oli alussa nopeaa muuttuu raskaaksi ja aina vain hitaammaksi, riski sille että jotain unohdetaan testata, tai testataan väärin kasvaa, tieto siitä miten rajapinnan ylipäätään piti toimia jää manuaalisen dokumentaation varaan • Tässä ympäristössä tuska ja ahdistus kasvaa kasvamistaan
  • 23. Yksinkertaisia korjauksia • Aloita testaaminen HETI • Kirjoita ensimmäinen testi ennen kuin toteutus tekee mitään, aja se, ja totea sen epäonnistuvan. Lisää toteutusta, lisää testiä, jne. Refaktoroi. • Hyvä testi jää spesifikaatioksi tuleville kehittäjille/tiimeille siitä miten rajapinnan odotetaan toimivan, ja toimii apuna regressiotestauksessa kun myöhemmin tehdään muutoksia • Jos testin halutaan toimivan osana dokumentaatiota, se tulee kirjoittaa myös dokumentaatiomielessä – ei siis testProducts, vaan ’adding a new product should succeed when parameters are valid’ • Välineitä: curl, SoapUI, RestAssured, Spock, Fiddler • Kuormitustestauksen automatisointi: Gatling, JMeter
  • 24. Synti 6: Tietoturvan laiminlyöminen GET /prices?query=’;DELETE%20FROM%20prices;--’
  • 25. Tietoturvan laiminlyöminen • Pahin synti: Ei ollenkaan autentikaatiota, ei edes API Key • Tietoturvaa laiminlyödään tyypillisesti OWASP TOP 10 haavoittuvuuksissa, jotka ovat vaikeammin testattavissa/kontrolloitavissa • Spesifisempiä osa-alueita mm. • Security Misconfiguration • SQL Injection • DDOS hyökkäykset • Resurssien suojaus, pääseekö parametreja varioimalla tai fuzz testaamalla tekemään enemmän kuin pitäisi?
  • 27. Yksinkertaisia korjauksia • Ei niitä ole, tietoturva on usein alue jossa ei yleensä koeta olevan rahaa/aikaa tehdä asioita kunnolla/loppuun asti • Lisää haastetta tulee siitä että testaus ei ole helppoa/suoraviivaista • Tietoturvan suhteen ajattelu on usein: Tehdään sitten jotain kun jotain tapahtuu
  • 28. No, jotain muita korjauksia? • SSL ihan kaikkialla aina koko ajan • Heti alusta alkaen aseta rajoitus kutsuille joita yksi access token/käyttäjä voi tehdä aikayksikössä, esim. 1000/pv – tämä suojaa monelta – tee siitä kuitenkin token kohtainen helposti säädettävä arvo • Validoi kaikki syötteet, validoi pääsy resursseihin suhteessa käyttäjän oikeuksiin, aina • Allokoidaan tietoturvaan yksinkertaisesti enemmän rahaa ja aikaa, testaus edellä • Pidetään huoli että kehittäjillä on ainakin OWASP TOP 10 periaatteet tuoreessa mielessä, ja pariohjelmoinnissa/katselmoinnissa kiinnitetään näihin huomiota • Testausta voidaan osin automatisoida, osaksi prosessia, esim. OWASP ZAP Proxy • Tarvittaessa auditointi/katselmointi, penetraatiotestaus/hackathon tapahtuma, bug bounty • Fiksu monitorointi paljastaa aikaisin hyökkäysyrityksiä, toistuvia pommituksia voidaan tunnistaa ja hidastaa • DDOS hyökkäyksiin ei ole helppoja keinoja, mutta user tokenit, fiksut reitittimet ja palomuurit, skaalautuva kapasiteetti auttavat • Pilvestä saa kaikkea tätä helpommin, jos on valmis maksamaan • Uutuutena myös GDPR tietosuoja-asioiden huomioiminen koko elinkaaren ajan, mm. testidata
  • 29. Synti 7: Vikasietoisuuden laiminlyönti Koko ajan hajalla
  • 30. Monitoroinnin ja seurannan laiminlyönti • Missä ja miten näkyy kun sovellus ei toimi? Jos vastaus on, että asiakaspalveluun alkaa tulemaan loppukäyttäjiltä soittoja, vastaus on väärä. • Miten pitkään kestää toipuminen? Ja yleensä virheen havaitseminen siitä kun se tapahtuu? Voiko ongelmia ennustaa? • Saadaanko kiinni hyökkäysyrityksiä? Pystytäänkö niitä blokkaamaan ja toipumaan niistä?
  • 31. Vikasietoisuuden unohtaminen • Kun palvelua pyöritetään tarpeeksi pitkään, kaikenlaista tapahtuu • Levy hajoaa, tietokanta hajoaa, verkkoyhteys sisäverkossa katkeaa, verkkoyhteys ulkoverkossa katkeaa, sertifikaatit vanhenevat vahingossa, rajapintaan kohdistuu DDOS hyökkäys • Osaan näistä vastauksen pitäisi olla prosessi ja ylläpito. Mutta osaa on vaikeaa nähdä edeltä. Silloin pitäisi olla tiedossa sovelluksen haluttu palvelutaso, ja vikasietoisuus. • Pari kysymystä: • Miten pitkään sovellus saa olla maissa? • Miten pitkältä ajalta voidaan menettää dataa? • Miten nopeasti sovellus pitää saada toipumaan täydellisessä katastrofissa?
  • 32. Muita syntejä • Strategian puute – kuka APIa käyttää, mikä on sen elinkaari, ja rooli? • Elinkaaresta, versioiden hallinnasta, muutosten tiedottamisesta on jo puhuttu aiemmin, kuitenkin tärkeää! Laiminlyönnit näillä alueilla näkyvät tuskana • Muutetaanko API ilman varoitusta vai jääkö se ennalleen, ja uusi löytyy osoitteessa /api/v2/accounts ? • Vaihtelevat käytännöt jopa saman API:n sisällä! • HATEOAS? VAI HATE HATEOAS? • Ei sivutusta, /all palauttaa ennen pitkää miljoonia tietueita • Microservices helvetti! • Jouston puute rajapinnoissa • Liian vaikea käyttää, toimii epävarmasti
  • 34. Ei se mitään! Useimmat synnit on onneksi sovitettavissa • REST ei kuitenkaan ole uskonto, vaan työväline – on hyvä ensin varmistaa että tuntee sen hyvin, pro-tasolla voidaan sitten harkiten rikkoa sääntöjä – kunhan synti on johdonmukaista, ja tiimi ja API käyttäjät ymmärtävät • Eli, aivan ensiksi, avaa muutama nettiresurssi API Design aiheesta, ja pari tuntia aikaa. Perehdy, opi, haasta. • Jos REST hankaa vastaan, ei hätää. Se on hyvä paketti mutta ei sovi joka käyttöön ja tuskin on rajapintojen viimeinen totuus. Aina tulee uutta ja vaihtoehtoista, jos se ei toimi, vaihda se. • Aika paljon auttaa hyvät kehityskäytännöt, kuten peer review, team review, jne, jossa voidaan keskustella yksityiskohdista ja yhtenäistää niitä • Usein projekteissa saattaa olla päinvastoin: Kopioidaan jonkun tekemiä huonoja tapoja miettimättä niitä, ja ne jäävät käytössä oleviksi antipatterneiksi • Yhtälailla kannattaa aina välillä kurkata miten muut tekevät rajapintoja oman kuplan ulkopuolella – erinomainen tilaisuus on myös aina kun tiimiin tulee ulkopuolelta tuoreita silmiä!
  • 35. Yhteenveto • Luota/Nojaa vahvasti HTTP protokollaan. Se on yksinkertainen robusti protokolla, jossa on keinoja jo varsin pitkälle. Tämä koskee eritoten REST rajapintoja. • Virhekäsittely? HTTP status/virhekoodit. Verbit? HTTP verbit GET, POST, PUT, DELETE. Suojausmekanismit? HTTPS, ja headerit. Tilasiirtymät? Linkkejä pitkin. • Tunne teknologiasi. Ei ole ideana tehdä rajapintoja kopioiden viiden minuutin tutoriaaleja ja kopioiden samoja virheitä, tai mallia joka ei skaalaudu oikeaan käyttöön isommassa tiimissä. Käytä vartti ja lue muutamasta lähteestä lisää, etenkin alkuperäislähteistä. • Tiedätkö mikä ero on PUT ja POST välillä? Mitä rajapinta palauttaa kun ei palauteta sisältöä? Mitä palautetaan PUT metodissa? Entä POST? • Normaalit kujeet, testaa aikaisin, testaa jatkuvasti, syö omaa koiranruokaasi (yuk), rakenna se kuin sen käyttäjä olisi psykopaatti joka tuntee osoitteesi, jne
  • 36. Kiitoksia! ARTO SANTALA Software Architect 050 5747452 arto.santala@solita.fi

Editor's Notes

  • #2: https://www.toptal.com/api-developers/5-golden-rules-for-designing-a-great-web-api
  • #37: https://twitter.com/SolitaOy https://www.facebook.com/Solita https://www.linkedin.com/company/solita-oy/ https://www.youtube.com/user/SolitaOy