Yleistä RESTistä
REST-palvelu on yleinen tapa toteuttaa tietopalvelun rajapinta web-palvelulle. REST-palvelu on ulospäin itse asiassa kuin ”perinteinen” HTTP-palvelu ja REST-rajapinta vastaa samoihin pyyntöihin kuin perus HTTP-palvelin. Myös HTTP -statuskoodit ovat käytössä eli onnistunut REST-palvelupyynnön käsittely palauttaa statuskoodin 200 OK, epäonnistunut tiedonhaku (vaikkapa haku id:llä jota ei löydy tietokannasta) palauttaa statuskoodin 404 Not found, jne.
Erona perus HTTP-palvelimeen/palveluun on, että paluuviestinä ei saada HTML-sivua vaan tyypillisesti JSON-muotoinen vastaus. Formaatti REST-palvelussa on tyypillisesti JSON mutta voisi olla myös XML. JSON on helposti hyödynnettävissä JavaScriptissä ja se voidaan tallentaa ilman muunnosta suoraan no-sql tietokantaan (esim. MongoDB) joten se on kätevä ja suosittu formaatti.
REST verbit (=metodit)
Seuraavassa esitellään yleinen REST-palveluiden käyttämä HTTP-verbien käyttötapa. Kyseessä on siis yleinen käytäntö, mutta ei tietenkään pakollinen ”sapluuna” vaan palvelun toteuttaja päättää millaisella käytännöllä palvelua käytetään.
GET Tietopyyntö jolla haetaan tallennettua dataa. Esimerkiksi pyyntö GET http://palvelu.net/asiakkaat palauttaa listan asiakkaista. Pyynnössä voidaan myös yksilöidä, mikä datayksilö halutaan hakea. Silloin osoitteeseen lisätään haettavan tietueen id, esimerkiksi GET http://palvelu.net/asiakkaat/f310e311-93e5-43ae-be0a-71628a147b90.
POST Tiedon tallennus. Esimerkiksi osoitteeseen http://palvelu.net/asiakkaat postattu JSON muotoinen sisältö {”nimi”:”Aku Ankka”, ”address”: ”Paratiisitie 13”} tallettaisi Aku Ankan asiakastietoihin. Paluuviestissä saadaan tallennettu tietue varustettuna id:llä, jos tallennus onnistui.
PUT Tiedon päivitys eli update. Palvelupyynnön mukana annetaan taas tiedot kuten POST-pyynnössä mutta tällä kertaa mukana on tietueen id, jotta päivitys osataan kohdistaa ko. riviin. Esim. PUT http://palvelu.net/asiakkaat/f310e311-93e5-43ae-be0a-71628a147b90 ja content osiossa tietueen tiedot {”nimi”:”Aku Ankka”, ”address”: ”Hanhivaaranpolku 22”} .
DELETE Tiedon poisto. Luonnollisesti yleensä järkevä vain kun kohdistetaan tiettyyn tietoriviin, id:llä osoitettuna, esim. DELETE http://palvelu.net/asiakkaat/f310e311-93e5-43ae-be0a-71628a147b90. Mikään ei tietysti estä toteuttamasta DELETE-operaatiota myös osoitteelle http://palvelu.net/asiakkaat siten että pyyntö poistaisi kaikki asiakastiedot, mutta tämä ei yleensä liene kovin järkevää.
Muitakin HTTP-verbejä voidaan käyttää, mutta yllä ehkä tärkeimmät.
Tarkemmin REST verbeistä esim. täältä:
http://www.restapitutorial.com/lessons/httpmethods.html
REST palvelun testaustyökalu selaimeen
Olemassa olevia REST-palveluita on helpointa testata selaimeen asennetun POSTER-lisäosan avulla. Kun selaimeen asentaa POSTER lisäosan (tällä nimellä löytyy ainakin Firefoxiin ja Cromeen) niin selaimen valikosta saa kätevästi käyntiin testerin jolla voi tehdä pyyntöjä REST-palveluihin ja tarkastella saatua vastausta. Alla kuva Firefoxissa toimivasta POSTER add-onista:
Posterilla on helppo lähettää REST-palveluun erityyppisiä pyyntöjä ja katsoa mitä tulee vastaukseksi.
Latauslinkki : POSTER AddOn for Firefox:
https://addons.mozilla.org/en-US/firefox/addon/poster/
Työkalu käynnistyy Firefoxin Tools-valikosta.
REST-palvelun toteutus Node.js:llä
Toteutamme seuraavaksi yksinkertaisen REST-palvelun joka vastaa POST, GET ja DELETE pyyntöihin, tallentaen ja hakien dataa JSON-muodossa. GET ilman parametreja palauttaa kaikki tietoalkiot tai jos parametrina annetaaan id, palautetaan alkio kyseisellä id:llä. POST generoi alkiolle uuden id:n, tallentaa alkion palvelun sisäiseen taulukkoon ja lopuksi palauttaa alkion id:llä varustettuna takaisin kutsujalle. DELETE poistaa tiedot annetulla id:llä.
Palvelun toteutus olettaa että Node.js:lle on ladattu expess ja body-parser kirjastot.
var express = require('express'); // for easy HTTP server
var application = express();
var bodyParser = require('body-parser');
application.use(bodyParser.urlencoded({
extended: true
}));
application.use(bodyParser.json());
// this is needed to allow connection from any address:
application.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Allow-Methods", "GET,POST,DELETE"); // PUT is not implemented
next();
});
// array to store items
var items = [];
// POST
application.post('/items/', function (req, res) {
console.log('POST received');
console.log(req.body);
var item = req.body;
var id = generateGuid();
item.id = id;
console.log(id);
items.push(item);
var responseItem = JSON.stringify(item);
res.end(responseItem);
});
// This is one way to generate new id
function generateGuid() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
return v.toString(16);
});
}
// GET: get all items
application.get('/items/', function (req, res) {
console.log('GET all received');
var responseItems = JSON.stringify(items);
res.end(responseItems);
});
// GET: get item(s) with id
application.get('/items/:id', function (req, res) {
console.log('GET with id received');
var filtered = items.filter(x => x.id==req.params.id);
var responseJSON = JSON.stringify(filtered);
res.end(responseJSON);
});
// DELETE: delete item(s) ith id
application.delete('/items/:id', function(req, res) {
console.log('DELETE with id received');
items = items.filter(i=>i.id!=req.params.id);
res.send({success : true});
});
// Start server
var server = application.listen(8080, function () {
var port = server.address().port;
console.log('Simple REST API listening on port %s', port);
});
Seuraavaksi käynnistetään yllä toteutettu palvelu komentoriviltä:
Sitten käynnistetään testaustyökalu eli POSTER lisäosa selaimesta.
Ensimmäinen palvelupyyntö on uuden tiedon tallennus POST metodilla jonka vastauksena saadaan 200 OK ja tallennettu tieto id:llä varustettuna:
Tallennetaan saman tien toinen tieto:
Sitten haetaan tiedot GET pyynnöllä ja vastauksena saadaan kaksi tietoalkiota:
Kokeillaan poistaa toinen tietoalkio DELETE pyynnöllä (huomaa id parametrina urlissa):
Kun nyt tehdään vielä yksi GET pyyntö, nähdään että toinen tietoalkio on poistunut palvelimelta:
Yhteenvetona voidaan todeta että Node.js:llä on todella helppo pystyttää yksinkertainen REST-palvelu joka käyttää JSON formaattia tiedon välittämiseen.






