Aina kun lähden matkoille, tässä tapauksessa kesämökille, haluan varmistaa, että saan tarvittaessa yhteyden kotikoneeseeni. Tämä tarkoittaa, että minun on tiedettävä kotona olevan nettiyhteyden IP-osoite, joka saattaa vaihtua silloin tällöin.

Päätin kokeilla, miten Amazonin uusi API Gateway toimisi tähän tarkoitukseen. Kotikoneella pyörivä cron-job ottaisi säännöllisesti yhteyden pilvessä olevaan API-rajapintaan, joka näkisi mistä IP-osoitteesta pyyntö tulee ja päivittäisi sen Lambda-funktiolla Route 53:n DNS-tietueeseen.

Projektiin kului aikaa muutama tunti ja se oli opettavainen. Amazonin API Gateway on pääosin hyvin yksinkertainen ja suoraviivainen käyttää. API-rajapintojen julkaiseminen sekä niiden kytkeminen Lambda-funktioihin hoituu GUI:ta klikkailemalla. Ongelmia alkoi tulla eteen vasta siinä vaiheessa, kun Lambda-funktiosta käsin piti päästä lukemaan HTTP-clientin IP-osoite

Tämä onnistui lopulta tekemällä kaksi pientä konfiguraatiomuutosta API Gatewayhin. Ensinnäkin rajapinnan Method Request -asetuksiin piti lisätä HTTP Request Header nimeltä X-Forwarded-For. Amazon lisää tämän otsakkeen automaattisesti ja se sisältää alkuperäisen HTTP-pyynnön lähettäjän IP-osoitteen, sekä myös mahdollisia muita matkan varrella proxyissa käytettyjä IP-osoitteita pilkuilla eroteltuina.

Toinen muutos oli hieman monimutkaisempi. Rajapinnan Integration Request -asetuksiin piti lisätä uusi Template, jonka Content-Type on application/json. Tämä tehtiin painamalla oikeassa järjestykessä ensin +-painiketta ja lopuksi tallennuspainiketta. Input Mapping -kenttään tarvittiin vielä seuraavanlainen koodinpätkä (ennen tallentamispainikkeen painamista ja uuden API-version Deployaamista):

{ "ip": "$input.params('x-forwarded-for'))" }

Näiden muutosten jälkeen Lambda-funktio näkee pyynnön lähettäneen HTTP-clientin IP-osoitteen parametrissä event.ip. Siitä se on helppo tallentaa AWS SDK:lla Route 53:een UPSERT-muutospyyntönä.

Vastaavalla tavalla voidaan välittää muitakin parametrejä. Eräs kätevä kikka on lisätä HTTP POST -pyynnössä mukana tullut JSON-dokumentti kokonaisuudessaan event.body -parametriksi. Tällöin API-asetuksissa ei tarvitse luetella erikseen jokaista JSON-kenttää. Huomaa, että tässä tapauksessa $input.json('$') ei ole lainausmerkkien sisällä:

{ "body": $input.json('$') }

Tämä kikka löytyi AWS-keskustelufoorumilta. Se liittyi muutama päivä sitten julkaistuun blogikirjoitukseen, joka kritisoi API Gatewayn puutteita. Kritiikki olikin paikallaan, mutta Amazon näyttää myös vastaavan siihen ja lisäävän puuttuvia ominaisuuksia.

Itse arvioisin API Gatewayn olevan yhdessä Lambda-funktioiden kanssa hyvinkin käyttökelpoinen tuote. Ongelma tullee vielä eteen siinä vaiheessa, kun pyyntöjä täytyy auktorisoida eri tavoin, mutta palaan siihen myöhemmin.

Published 20.7.2015