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
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?
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

Similar to API Design: 7 kuolemansyntiä

Sovellusvirtualisointi - Mitä missä milloin 2015
Sovellusvirtualisointi - Mitä missä milloin 2015Sovellusvirtualisointi - Mitä missä milloin 2015
Sovellusvirtualisointi - Mitä missä milloin 2015
Teemu Tiainen
 
JavaScript Frameworkit, jotka kannattaa tuntea
JavaScript Frameworkit, jotka kannattaa tunteaJavaScript Frameworkit, jotka kannattaa tuntea
JavaScript Frameworkit, jotka kannattaa tuntea
Sovelto
 
Syvemmälle javaan
Syvemmälle javaanSyvemmälle javaan
Syvemmälle javaan
Arto Santala
 
Windows 8 yrityksen työasemana
Windows 8 yrityksen työasemanaWindows 8 yrityksen työasemana
Windows 8 yrityksen työasemana
Sovelto
 
Mihin robotit hajoavat?
Mihin robotit hajoavat?Mihin robotit hajoavat?
Mihin robotit hajoavat?
Integrata Oy
 
Oulu clojure-meetup-20181113
Oulu clojure-meetup-20181113Oulu clojure-meetup-20181113
Oulu clojure-meetup-20181113
Tatu Tarvainen
 
Vincit Teatime 2015.2 - Aleksi Häkli: SaaSiin pa(i)nostusta
Vincit Teatime 2015.2 - Aleksi Häkli: SaaSiin pa(i)nostustaVincit Teatime 2015.2 - Aleksi Häkli: SaaSiin pa(i)nostusta
Vincit Teatime 2015.2 - Aleksi Häkli: SaaSiin pa(i)nostusta
VincitOy
 
Azure JKL Keynote 9.11.2017
Azure JKL Keynote 9.11.2017Azure JKL Keynote 9.11.2017
Azure JKL Keynote 9.11.2017
Jouni Heikniemi
 
Mainostoimisto Kanava.to – Webortaasi2013
Mainostoimisto Kanava.to – Webortaasi2013Mainostoimisto Kanava.to – Webortaasi2013
Mainostoimisto Kanava.to – Webortaasi2013
Mainostoimisto Kanava.to
 
Liferay Road Show Sosiaali- ja terveysministeriö
Liferay Road Show Sosiaali- ja terveysministeriöLiferay Road Show Sosiaali- ja terveysministeriö
Liferay Road Show Sosiaali- ja terveysministeriö
Ambientia
 
Pragmatic Agile - Aamiaistilaisuus
Pragmatic Agile - AamiaistilaisuusPragmatic Agile - Aamiaistilaisuus
Pragmatic Agile - Aamiaistilaisuus
Nitor
 
Java - analysointityökaluja
Java - analysointityökalujaJava - analysointityökaluja
Java - analysointityökaluja
Kari Sarsila
 
Scrumin nykytila ja kehitys
Scrumin nykytila ja kehitysScrumin nykytila ja kehitys
Scrumin nykytila ja kehitys
Sovelto
 
Vincit Teatime 2015 - Heikki Salo: Case ZenRobotics: JavaScriptin äärirajoilla
Vincit Teatime 2015 - Heikki Salo: Case ZenRobotics: JavaScriptin äärirajoillaVincit Teatime 2015 - Heikki Salo: Case ZenRobotics: JavaScriptin äärirajoilla
Vincit Teatime 2015 - Heikki Salo: Case ZenRobotics: JavaScriptin äärirajoilla
VincitOy
 
Net ohjelmointi kertaus
Net ohjelmointi kertausNet ohjelmointi kertaus
Net ohjelmointi kertausTimo Tanila
 
AgileJKL Meetup 2016 - Antti Vartiainen
AgileJKL Meetup 2016 - Antti VartiainenAgileJKL Meetup 2016 - Antti Vartiainen
AgileJKL Meetup 2016 - Antti Vartiainen
Digia Plc
 
Guru days 5.10.2011 html5 ja silverlight
Guru days 5.10.2011   html5 ja silverlightGuru days 5.10.2011   html5 ja silverlight
Guru days 5.10.2011 html5 ja silverlightSalcom Group
 
10 parasta tapaa pilata Liferay-projekti
10 parasta tapaa pilata Liferay-projekti10 parasta tapaa pilata Liferay-projekti
10 parasta tapaa pilata Liferay-projekti
Ambientia
 
Tietoturvaa it kehitykselle 12 2012
Tietoturvaa it kehitykselle 12 2012Tietoturvaa it kehitykselle 12 2012
Tietoturvaa it kehitykselle 12 2012
Tomppa Järvinen
 

Similar to API Design: 7 kuolemansyntiä (20)

Sovellusvirtualisointi - Mitä missä milloin 2015
Sovellusvirtualisointi - Mitä missä milloin 2015Sovellusvirtualisointi - Mitä missä milloin 2015
Sovellusvirtualisointi - Mitä missä milloin 2015
 
JavaScript Frameworkit, jotka kannattaa tuntea
JavaScript Frameworkit, jotka kannattaa tunteaJavaScript Frameworkit, jotka kannattaa tuntea
JavaScript Frameworkit, jotka kannattaa tuntea
 
Syvemmälle javaan
Syvemmälle javaanSyvemmälle javaan
Syvemmälle javaan
 
Windows 8 yrityksen työasemana
Windows 8 yrityksen työasemanaWindows 8 yrityksen työasemana
Windows 8 yrityksen työasemana
 
Mihin robotit hajoavat?
Mihin robotit hajoavat?Mihin robotit hajoavat?
Mihin robotit hajoavat?
 
Oulu clojure-meetup-20181113
Oulu clojure-meetup-20181113Oulu clojure-meetup-20181113
Oulu clojure-meetup-20181113
 
Vincit Teatime 2015.2 - Aleksi Häkli: SaaSiin pa(i)nostusta
Vincit Teatime 2015.2 - Aleksi Häkli: SaaSiin pa(i)nostustaVincit Teatime 2015.2 - Aleksi Häkli: SaaSiin pa(i)nostusta
Vincit Teatime 2015.2 - Aleksi Häkli: SaaSiin pa(i)nostusta
 
Azure JKL Keynote 9.11.2017
Azure JKL Keynote 9.11.2017Azure JKL Keynote 9.11.2017
Azure JKL Keynote 9.11.2017
 
Mainostoimisto Kanava.to – Webortaasi2013
Mainostoimisto Kanava.to – Webortaasi2013Mainostoimisto Kanava.to – Webortaasi2013
Mainostoimisto Kanava.to – Webortaasi2013
 
Liferay Road Show Sosiaali- ja terveysministeriö
Liferay Road Show Sosiaali- ja terveysministeriöLiferay Road Show Sosiaali- ja terveysministeriö
Liferay Road Show Sosiaali- ja terveysministeriö
 
Pragmatic Agile - Aamiaistilaisuus
Pragmatic Agile - AamiaistilaisuusPragmatic Agile - Aamiaistilaisuus
Pragmatic Agile - Aamiaistilaisuus
 
Java - analysointityökaluja
Java - analysointityökalujaJava - analysointityökaluja
Java - analysointityökaluja
 
Scrumin nykytila ja kehitys
Scrumin nykytila ja kehitysScrumin nykytila ja kehitys
Scrumin nykytila ja kehitys
 
Vincit Teatime 2015 - Heikki Salo: Case ZenRobotics: JavaScriptin äärirajoilla
Vincit Teatime 2015 - Heikki Salo: Case ZenRobotics: JavaScriptin äärirajoillaVincit Teatime 2015 - Heikki Salo: Case ZenRobotics: JavaScriptin äärirajoilla
Vincit Teatime 2015 - Heikki Salo: Case ZenRobotics: JavaScriptin äärirajoilla
 
Net ohjelmointi kertaus
Net ohjelmointi kertausNet ohjelmointi kertaus
Net ohjelmointi kertaus
 
AgileJKL Meetup 2016 - Antti Vartiainen
AgileJKL Meetup 2016 - Antti VartiainenAgileJKL Meetup 2016 - Antti Vartiainen
AgileJKL Meetup 2016 - Antti Vartiainen
 
EPiServer7-MVC
EPiServer7-MVCEPiServer7-MVC
EPiServer7-MVC
 
Guru days 5.10.2011 html5 ja silverlight
Guru days 5.10.2011   html5 ja silverlightGuru days 5.10.2011   html5 ja silverlight
Guru days 5.10.2011 html5 ja silverlight
 
10 parasta tapaa pilata Liferay-projekti
10 parasta tapaa pilata Liferay-projekti10 parasta tapaa pilata Liferay-projekti
10 parasta tapaa pilata Liferay-projekti
 
Tietoturvaa it kehitykselle 12 2012
Tietoturvaa it kehitykselle 12 2012Tietoturvaa it kehitykselle 12 2012
Tietoturvaa it kehitykselle 12 2012
 

More from Arto Santala

Your Brain on Java
Your Brain on JavaYour Brain on Java
Your Brain on Java
Arto Santala
 
Java On Speed
Java On SpeedJava On Speed
Java On Speed
Arto Santala
 
Migrating to Java 11
Migrating to Java 11Migrating to Java 11
Migrating to Java 11
Arto Santala
 
Leaner microservices with Java 10
Leaner microservices with Java 10Leaner microservices with Java 10
Leaner microservices with Java 10
Arto Santala
 
Automate Everything! (No stress development/Tallinn)
Automate Everything! (No stress development/Tallinn)Automate Everything! (No stress development/Tallinn)
Automate Everything! (No stress development/Tallinn)
Arto Santala
 
Solita /dev/cloud kickstart
Solita /dev/cloud kickstartSolita /dev/cloud kickstart
Solita /dev/cloud kickstart
Arto Santala
 
Kontit pomppimaan3
Kontit pomppimaan3Kontit pomppimaan3
Kontit pomppimaan3
Arto Santala
 
Java9 moduulit jigsaw
Java9 moduulit jigsawJava9 moduulit jigsaw
Java9 moduulit jigsaw
Arto Santala
 
JavaOne 2016 short highlights
JavaOne 2016 short highlightsJavaOne 2016 short highlights
JavaOne 2016 short highlights
Arto Santala
 

More from Arto Santala (9)

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

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
  • 20.
  • 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?
  • 26.
  • 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

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