Lag et API på 1-2-3 med Node og Express

Lag et API på 1-2-3 med Node og Express

På samme måte som det er lurt å ikke legge alle eggene i samme kurv, er det lurt å fordele ansvar i applikasjonen din. Dette er fordi modulær kode som regel er enklere å utvikle, debugge, teste og vedlikeholde. Brukergrensesnittet bør ikke ha ansvar for å hente eller bearbeide eksterne data. Det er oppgaven til et tjenestelag, mellomvare eller et API. Dette lager du lett med Node og Express!

Jo større og mer kompleks en applikasjon blir, jo viktigere er det å fordele ansvar mellom komponentene. Det vil, som regel, gi deg mindre å tenke på når du skal viderutvikle, vedlikeholde eller bytte ut funksjonalitet.

En vanlig måte å fordele ansvar mellom brukergrensesnittet og datalagret er å bruke en mellomvare-komponent, eller et tjenestelag som både leverer og tar i mot data.

Tradisjonelt har disse løsningene vært laget i Java eller .Net, men det er ingen grunn til at du ikke kan bruke en node-server, og som frontend-utvikler har du antakelig mer enn nok JavaScript-kompetanse til å klare det.

Denne artikkelen forutsetter at du har basis-kunnskaper om Node, og npm, ellers kan du få en liten innføring her

Opprett prosjektet

$ mkdir api-demo
$ cd api-demo

deretter oppretter du et npm-prosjekt med en package.json-fil, i dette eksempelet bruker jeg -y for å opprette med standard-verdier.

$ npm init -y

Så må du installere de bibliotekene vi skal bruke: Express og Firebase. Les mer om bruk av Firebase. Merk --save for å lagre avhengighetene i prosjeketet.

$ npm install --save express firebase

Deretter oppretter du en app.js; serveren med vårt API.

$ touch app.js

Åpne filen i editoren din og lim inn følgende:

Når du har lagret filen kan du starte serveren med

$ node app

og navigere til http://localhost:5555

Du bør få følgende beskjed i konsollet:

API lytter på port: 5555

Og i nettleseren:

API oppe!

Lese fra datalager

Vi skal lage metoder i APIet som henholdsvis leser og skriver til en Firebase. For å følge eksempelet er det fint om du oppretter din egen database, ellers du kan bruke https://reactfire-demo.firebaseio.com som er brukt i denne artikkelen, merk at innholdet i denne databasen nullstilles jevnlig.

Vi utvider app.js slik:

Forsøk deg med: http://localhost:5555/text/-JiEPn2FMzEZldTFUmxp

Som bør resultere i et json-objekt som ser slik ut:

{"text": "Some text in the Firebase"}

Merk deg at den metoden som leser fra Firebase benytter Promises, som du blant annet kan lese om i Jake Archibalds glimrende artikkel om temaet. Denne teknologien er en del av ECMAScript 2015, og ikke implementert i alle browsere ennå. Sjekk browseren din her

Skrive til datalager

Applikasjoner har ofte ett eller flere skjema, som bruker kan fylle informasjon inn i. I dette eksempelet har vi ikke noe brukergrensesnitt, bortsett fra adressefeltet i nettleseren, og etterhvert en REST-klient. Det gir en god illustrasjon på kommunikasjon som ofte brukes. Vi skal derfor lage en enkel rute på serveren vår, med en metode som tar i mot litt data basert på data i URL'en til ruten, og persisterer disse til databasen.

Tenk deg at du skal lage en tjeneste, som hvem som helst skal kunne benytte, og som tar i mot et stedsnavn, et brukernavn og en temperatur. Dette skal sendes til tjenesten, som så skal lagre det. Tjenestekallet vil da kunne se slik ut:

http://[server-navn]/temperatureposting/create/kallekanin/Oslo/20

hvor ruten utgjør 

temperatureposting/create/

og de tre siste elementene i URL'en utgjør data vi sender; brukernavn, sted og lokasjon.

Dette tjenestekallet tilfredsstiller formkravene til et såkalt REST-kall. Som du ser av det første kallet du gjorde; /text/:id så følger REST enkelte navnekonvensjoner, som eksempelvis å benytte substantiver for ressurser og verb for å indikere en handling som ønskes utført ressursen. I det første kallet, ber vi om en «text» med en spesifik ID, vi trenger ikke å spesifisere et verb her, det er gitt ved GET-requesten.

De aller fleste behov vil kunne dekkes ved enkle GET-requests, også det å skrive til en ressurs, men den strikte tolkningen av REST vil nok si at dette er en POST. Grunnen til det er at vi ikke vet den fulle URL til den ressursen vi skal opprette, ettersom det er Firebase som oppretter ID'enunder lagring. Vi kan instruere Firebase og sende med våre egen ID, og da ville en PUT være det korrekte, men da må vi i så fall generere unike nøkler, eller på annen måte få tak i disse på.

Jeg foretrekker å bruke path parameter fremfor query parameter, fordi det da er enklere å vurdere om man skal benytte en POST eller PUT, jeg synes også koden som regel er enklere å lese og URL'ene blir som regel kortere og penere, men det er litt opp til deg selv hva du ønsker å gjøre, det er forskjellige metoder for å hente ut data, og Express klarer fint begge:

Path parameter:

http://[server-navn]/temperatureposting/create/kallekanin/Oslo/20

Query parameter:

http://[server-navn]/temperatureposting/create?userid=kallekanin&location=Oslo&temperature?=20

Vi kan nå også enkelt lage en ny GET basert på den ressursen vi akkurat la inn, en slik URL vil da se slik ut:

http://[server-navn]/temperatureposting/:id

implementert:

http://[server-navn]/temperatureposting/-K19477WvueJCnHoL_WD

Og den endelige koden ser da slik ut:

Merk at det nå finnes en rute for å ta i mot en POST-request, med userid, location og temperature og en rute for en GET-request med Firebase-nodeId 

Ettersom vi skal bruke, min, strikte tolkning av REST, og gjøre en POST, så trenger vi et annet verktøy enn adressefeltet i nettleseren, det finnes flere glimrende verktøy for Chrome; Postman, Advanced REST client og RESTClient eller REST Easy for Firefox, eller du kan bruke cURL fra kommandolinja. Jeg bruker vanligvis Advanced REST Client og da ser kallet slik ut: 

Advanced Rest Client - med PUT request
Advanced REST client med en POST

Når du nå har lagret en ressurs, det ser du av den grønne 200-OK statusen, og at responsen inneholder database ID nederst i bildet, kan du  jo forsøke å hente bildet ut igjen.

Naviger til 

http://localhost:5555/temperatureposting/

Du vil få en melding som sier 

Cannot GET /temperatureposting/

Men om du kopierer nøkkelen fra POST-requesten du nettop har gjort, og limer den inn til slutt i adressefeltet vil du få tilbake en liknende respons:

Og mer er det egentlig ikke til det, husk å sikre API og datalager, og lykke til med RESTen ;)

Mer lesing

REST
REST - best practises på Google
Path params vs Query params på Google
Express
Firebase-dokumentasjon
Node-dokumentasjon
npm-dokumentasjon
Javascript-promises

Kildekoden til denne artikkelen

 

Om bloggeren:
Frontendutvikler. Glad i Javascript. Har hakket sammen websider siden midten av 90-tallet, og trives godt med det.

comments powered by Disqus