REST API-vejledning - REST-klient, REST-service og API-opkald forklaret med kodeeksempler

Har du nogensinde spekuleret på, hvordan login / tilmelding på et websted fungerer på back-end? Eller hvordan når du søger efter "søde killinger" på YouTube, får du en masse resultater og er i stand til at streame fra en fjernmaskine?

I denne nybegyndervenlige guide vil jeg lede dig gennem processen med at oprette en RESTful API. Vi afklassificerer noget af jargongen og ser på, hvordan vi kan kode en server i NodeJS. Lad os dykke lidt dybere ned i JavaScript!

Få den jargon væk

Så hvad er REST? Ifølge Wikipedia:

Repræsentationstilstandsoverførsel ( REST ) er en software-arkitektonisk stil, der definerer et sæt begrænsninger, der skal bruges til at skabe webtjenester. RESTful webtjenester giver de anmodende systemer adgang til og manipulerer tekstrepræsentationer af webressourcer ved hjælp af et ensartet og foruddefineret sæt statsløse operationer

Lad os afmystificere, hvad det betyder (forhåbentlig har du den fulde form). REST er dybest set et sæt regler for kommunikation mellem en klient og server. Der er et par begrænsninger for definitionen af ​​REST:

  1. Client-Server Architecture : brugergrænsefladen på webstedet / appen skal adskilles fra dataanmodningen / lagringen, så hver del kan skaleres individuelt.
  2. Statsløshed : Kommunikationen bør ikke have nogen klientkontekst gemt på serveren. Dette betyder, at hver anmodning til serveren skal foretages med alle de krævede data, og der skal ikke antages nogen antagelser, hvis serveren har data fra tidligere anmodninger.
  3. Lagdelt system : klienten skal ikke være i stand til at fortælle, om den kommunikerer direkte med serveren eller en formidler. Disse mellemliggende servere (det være sig proxy- eller load balancere) giver mulighed for skalerbarhed og sikkerhed for den underliggende server.

Okay, så nu hvor du ved, hvad RESTful-tjenester er, her er nogle af de udtryk, der bruges i overskriften:

  1. REST-klient : kode eller en app, der kan få adgang til disse REST-tjenester. Du bruger en lige nu! Ja, browseren kan fungere som en ukontrolleret REST-klient (webstedet håndterer browseranmodningerne). Browseren brugte i lang tid en indbygget funktion kaldet XMLHttpRequest til alle REST-anmodninger. Men dette blev efterfulgt af FetchAPI, en moderne, løftebaseret tilgang til anmodninger. Andre eksempler er kodebiblioteker som axios, superagent og got eller nogle dedikerede apps som Postman (eller en online version, postwoman!) Eller et kommandolinjeværktøj som cURL !.
  2. REST Service : serveren. Der er mange populære biblioteker, der gør oprettelsen af ​​disse servere til en leg, som ExpressJS til NodeJS og Django til Python.
  3. REST API : dette definerer slutpunktet og metoderne, der er tilladt til at få adgang til / sende data til serveren. Vi vil tale om dette i detaljer nedenfor. Andre alternativer til dette er: GraphQL, JSON-Pure og oData.

Så fortæl mig nu, hvordan ser REST ud?

I meget brede vendinger beder du serveren om bestemte data eller beder den om at gemme nogle data, og serveren svarer på anmodningerne.

I programmeringsbetingelser er der et slutpunkt (en URL), som serveren venter på at få en anmodning om. Vi opretter forbindelse til dette slutpunkt og sender nogle data om os (husk, REST er statsløs, ingen data om anmodningen er gemt), og serveren reagerer med det korrekte svar.

Ord er kedelige, lad mig give dig en demonstration. Jeg bruger Postbudmand til at vise dig anmodningen og svaret:

De returnerede data findes i JSON (JavaScript Object Notation) og kan tilgås direkte.

Her //official-joke-api.appspot.com/random_jokekaldes det et slutpunkt for en API. Der vil være en server, der lytter på dette slutpunkt for anmodninger som den, vi fremsatte.

RESTENS anatomi:

Okay, så nu ved vi, at klienten kan anmode om data, og serveren vil reagere korrekt. Lad os se dybere på, hvordan en anmodning dannes.

  1. Slutpunkt : Jeg har allerede fortalt dig om dette. For en opdatering er det URL'en, hvor REST-serveren lytter.
  2. Metode : Tidligere skrev jeg, at du enten kan anmode om data eller ændre dem, men hvordan vil serveren vide, hvilken slags operation klienten vil udføre? REST implementerer flere 'metoder' til forskellige typer anmodninger, følgende er mest populære:

    - : Hent ressource fra serveren.

    - POST : Opret ressource til serveren.

    - PATCH eller PUT : Opdater eksisterende ressource på serveren.

    - SLET : Slet eksisterende ressource fra serveren.

  3. Overskrifter : De yderligere oplysninger, der gives til kommunikation mellem klient og server (husk, REST er statsløs). Nogle af de almindelige overskrifter er:

    Anmodning:

    - vært : klientens IP (eller hvorfra anmodningen stammer)

    - accept-sprog : sprog forståeligt af klienten

    - user-agent : data om klient, operativsystem og leverandør

    Svar :

    - status : status for anmodning eller HTTP-kode.

    - indholdstype : type ressource, der sendes af serveren.

    - set-cookie : indstiller cookies efter server

  4. Data : (kaldes også brødtekst eller besked) indeholder oplysninger, du vil sende til serveren.

Nok med detaljerne - vis mig koden.

Lad os begynde at kode en REST-tjeneste i Node. Vi implementerer alle de ting, vi har lært ovenfor. Vi bruger også ES6 + til at skrive vores service i.

Sørg for, at du har Node.JS installeret nodeog npmer tilgængelig i din sti. Jeg bruger knude 12.16.2 og NPM 6.14.4.

Opret en mappe rest-service-nodeog cd ind i den:

mkdir rest-service-node cd rest-service-node

Initialiser nodeprojektet:

npm init -y

Den -yflaget springer alle spørgsmålene. Hvis du vil udfylde hele spørgeskemaet, skal du bare køre npm init.

Lad os installere nogle pakker. Vi bruger ExpressJS-rammen til udvikling af REST-serveren. Kør følgende kommando for at installere den:

npm install --save express body-parser

Hvad er body-parserder til? Express er som standard ikke i stand til at håndtere data sendt via POST-anmodning som JSON. body-parsertillader Express at overvinde dette.

Opret en fil, der hedder, server.jsog tilføj følgende kode:

const express = require("express"); const bodyParser = require("body-parser"); const app = express(); app.use(bodyParser.json()); app.listen(5000, () => { console.log(`Server is running on port 5000.`); }); 

De første to linjer importerer Express og body-parser.

Tredje linje initialiserer Express-serveren og indstiller den til en kaldet variabel app.

Linjen app.use(bodyParser.json());initialiserer body-parser-pluginet.

Endelig indstiller vi vores server til at lytte på port 5000for anmodninger.

Henter data fra REST-serveren:

For at få data fra en server har vi brug for en GETanmodning. Tilføj følgende kode før app.listen:

const sayHi = (req, res) => { res.send("Hi!"); }; app.get("/", sayHi);

We have created a function sayHi which takes two parameters req and res (I will explain later) and sends a 'Hi!' as response.

app.get() takes two parameters, the route path and function to call when the path is requested by the client. So, the last line translates to: Hey server, listen for requests on the '/' (think homepage) and call the sayHi function if a request is made.

app.get also gives us a request object containing all the data sent by the client and a response object which contains all the methods with which we can respond to the client. Though these are accessible as function parameters, the general naming convention suggests we name them res for response and req for request.

Enough chatter. Let's fire up the server! Run the following server:

node server.js

If everything is successful, you should see a message on console saying: Server is running on port 5000.

Note: You can change the port to whatever number you want.

Open up your browser and navigate to //localhost:5000/ and you should see something like this:

There you go! Your first GET request was successful!

Sending data to REST Server:

As we have discussed earlier, let's setup how we can implement a POST request into our server. We will be sending in two numbers and the server will return the sum of the numbers. Add this new method below the app.get :

app.post("/add", (req, res) => { const { a, b } = req.body; res.send(`The sum is: ${a + b}`); });

Here, we will be sending the data in JSON format, like this:

{ "a":5, "b":10 }

Let's get over the code:

On line 1, we are invoking the .post() method of ExpressJS, which allows the server to listen for POST requests. This function takes in the same parameters as the .get() method. The route that we are passing is /add, so one can access the endpoint as //your-ip-address:port/add or in our case localhost:5000/add. We are inlining our function instead of writing a function elsewhere.

On line 2, we have used a bit of ES6 syntax, namely, object destructuring. Whatever data we send via the request gets stored and is available in the body of the req object. So essentially, we could've replaced line 2 with something like:

const num1 = req.body.a; const num2 = req.body.b;

On line 3, we are using the send() function of the res object to send the result of the sum. Again, we are using template literals from ES6. Now to test it (using Postman):

So we have sent the data 5 and 10 as a and b using them as the body. Postman attaches this data to the request and sends it. When the server receives the request, it can parse the data from req.body , as we did in the code above. The result is shown below.

Alright, the final code:

const express = require("express"); const bodyParser = require("body-parser"); const app = express(); app.use(bodyParser.json()); const sayHi = (req, res) => { res.send("Hi!"); }; app.get("/", sayHi); app.post("/add", (req, res) => { const { a, b } = req.body; res.send(`The sum is: ${a + b}`); }); app.listen(5000, () => { console.log(`Server is running on port 5000.`); }); 

REST Client:

Okay, we have created a server, but how do we access it from our website or webapp? Here the REST client libraries will come in handy.

We will be building a webpage which will contain a form, where you can enter two numbers and we will display the result. Let's start.

First, let's change the server.js a bit:

const path = require("path"); const express = require("express"); const bodyParser = require("body-parser"); const app = express(); app.use(bodyParser.json()); app.get("/", (req, res) => { res.sendFile(path.join(__dirname, "index.html")); }); app.post("/add", (req, res) => { const { a, b } = req.body; res.send({ result: parseInt(a) + parseInt(b) }); }); app.listen(5000, () => { console.log(`Server is running on port 5000.`); }); 

We imported a new package path, which is provided by Node, to manipulate path cross-platform. Next we changed the GET request on '/' and use another function available in res, ie. sendFile, which allows us to send any type of file as response. So, whenever a person tries to navigate to '/', they will get our index.html page.

Finally, we changed our app.post function to return the sum as JSON and convert both a and b to integers.

Let's create an html page, I will call it index.html, with some basic styling:

     REST Client   * { margin: 0; padding: 0; box-sizing: border-box; } .container { height: 100vh; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; display: flex; flex-direction: column; justify-content: center; align-items: center; } form { display: flex; flex-direction: column; margin-bottom: 20px; } label, input[type="submit"] { margin-top: 20px; } 

Simple POST Form

Number 1: Number 2: Click Add!

Let's add a script tag just before the closing body tag, so we don't need to maintain a .js file. We will begin by listening for the submit event and call a function accordingly:

 document.addEventListener("submit", sendData); 

First we need to prevent page refresh when the 'Add' button is clicked. This can be done using the preventDefault() function. Then, we will get the value of the inputs at that instant:

function sendData(e) { e.preventDefault(); const a = document.querySelector("#num1").value; const b = document.querySelector("#num2").value; }

Now we will make the call to the server with both these values a and b. We will be using the Fetch API, built-in to every browser for this.

Fetch takes in two inputs, the URL endpoint and a JSON request object and returns a Promise. Explaining them here will be out-of-bounds here, so I'll leave that for you.

Continue inside the sendData() function:

fetch("/add", { method: "POST", headers: { Accept: "application/json", "Content-Type": "application/json" }, body: JSON.stringify({ a: parseInt(a), b: parseInt(b) }) }) .then(res => res.json()) .then(data => { const { result } = data; document.querySelector( ".result" ).innerText = `The sum is: ${result}`; }) .catch(err => console.log(err));

First we are passing the relative URL of the endpoint as the first parameter to fetch. Next, we are passing an object which contains the method we want Fetch to use for the request, which is POST in this case.

We are also passing headers, which will provide information about the type of data we are sending (content-type) and the type of data we accept as response (accept).

Next we pass body. Remember we typed the data as JSON while using Postman? We're doing kind of a similar thing here. Since express deals with string as input and processes it according to content-type provided, we need to convert our JSON payload into string. We do that with JSON.stringify(). We're being a little extra cautious and parsing the input into integers, so it doesn't mess up our server (since we haven't implemented any data-type checking).

Finally, if the promise (returned by fetch) resolves, we will get that response and convert it into JSON. After that, we will get the result from the data key returned by the response. Then we are simply displaying the result on the screen.

At the end, if the promise is rejected, we will display the error message on the console.

Here's the final code for index.html:

     REST Client   * { margin: 0; padding: 0; box-sizing: border-box; } .container { height: 100vh; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; display: flex; flex-direction: column; justify-content: center; align-items: center; } form { display: flex; flex-direction: column; margin-bottom: 20px; } label, input[type="submit"] { margin-top: 20px; } 

Simple POST Form

Number 1: Number 2: Click Add! document.addEventListener("submit", sendData); function sendData(e) { e.preventDefault(); const a = document.querySelector("#num1").value; const b = document.querySelector("#num2").value; fetch("/add", { method: "POST", headers: { Accept: "application/json", "Content-Type": "application/json" }, body: JSON.stringify({ a: parseInt(a), b: parseInt(b) }) }) .then(res => res.json()) .then(data => { const { result } = data; document.querySelector( ".result" ).innerText = `The sum is: ${result}`; }) .catch(err => console.log(err)); }

I have spun up a little app on glitch for you to test.

Conclusion:

So in this post, we learnt about REST architecture and the anatomy of REST requests. We worked our way through by creating a simple REST Server that serves GET and POST requests and built a simple webpage that uses a REST Client to display the sum of two numbers.

Du kan udvide dette til de resterende typer anmodninger og endda implementere en komplet back-end CRUD-app.

Jeg håber, du har lært noget af dette. Hvis du har spørgsmål, er du velkommen til at kontakte mig via twitter! Glad kodning!