REST-API-Lernprogramm - REST-Client-, REST-Service- und API-Aufrufe, die anhand von Codebeispielen erläutert werden

Haben Sie sich jemals gefragt, wie das Anmelden / Registrieren auf einer Website im Back-End funktioniert? Oder wie, wenn Sie auf YouTube nach "süßen Kätzchen" suchen, erhalten Sie eine Reihe von Ergebnissen und können von einem Remote-Computer streamen?

In diesem anfängerfreundlichen Handbuch werde ich Sie durch den Prozess des Einrichtens einer RESTful-API führen. Wir werden einen Teil des Jargons freigeben und uns ansehen, wie wir einen Server in NodeJS codieren können. Lassen Sie uns etwas tiefer in JavaScript eintauchen!

Holen Sie sich diesen Jargon weg

Was ist REST? Laut Wikipedia:

Representational State Transfer ( REST ) ist ein Software-Architekturstil, der eine Reihe von Einschränkungen definiert, die zum Erstellen von Webdiensten verwendet werden sollen. Mit RESTful Web Services können die anfordernden Systeme auf Textdarstellungen von Webressourcen zugreifen und diese bearbeiten, indem sie einen einheitlichen und vordefinierten Satz zustandsloser Vorgänge verwenden

Lassen Sie uns entmystifizieren, was das bedeutet (hoffentlich haben Sie die vollständige Form). REST ist im Grunde ein Satz von Regeln für die Kommunikation zwischen einem Client und einem Server. Bei der Definition von REST gibt es einige Einschränkungen:

  1. Client-Server-Architektur : Die Benutzeroberfläche der Website / App sollte von der Datenanforderung / -speicherung getrennt sein, damit jeder Teil einzeln skaliert werden kann.
  2. Statuslosigkeit : In der Kommunikation sollte kein Client-Kontext auf dem Server gespeichert sein. Dies bedeutet, dass jede Anforderung an den Server mit allen erforderlichen Daten erfolgen sollte und keine Annahmen getroffen werden sollten, wenn der Server Daten aus früheren Anforderungen enthält.
  3. Schichtsystem : Der Client sollte nicht erkennen können, ob er direkt mit dem Server oder einem Vermittler kommuniziert. Diese Zwischenserver (Proxy- oder Load-Balancer) ermöglichen Skalierbarkeit und Sicherheit des zugrunde liegenden Servers.

Okay, jetzt, da Sie wissen, was RESTful-Services sind, werden in der Überschrift einige der folgenden Begriffe verwendet:

  1. REST-Client : Code oder eine App, die auf diese REST-Services zugreifen kann. Sie verwenden gerade eine! Ja, der Browser kann als unkontrollierter REST-Client fungieren (die Website verarbeitet die Browseranforderungen). Der Browser verwendete lange Zeit eine integrierte Funktion namens XMLHttpRequest für alle REST-Anforderungen. Dies gelang jedoch mit FetchAPI, einem modernen, vielversprechenden Ansatz für Anfragen. Andere Beispiele sind Codebibliotheken wie Axios, Superagent und Got oder einige dedizierte Apps wie Postman (oder eine Online-Version, Postwoman!) Oder ein Befehlszeilentool wie cURL!.
  2. REST-Service : Der Server. Es gibt viele beliebte Bibliotheken, die die Erstellung dieser Server zum Kinderspiel machen, wie ExpressJS für NodeJS und Django für Python.
  3. REST-API : Definiert den Endpunkt und die Methoden, die für den Zugriff auf / die Übermittlung von Daten an den Server zulässig sind. Wir werden im Folgenden ausführlich darauf eingehen. Andere Alternativen dazu sind: GraphQL, JSON-Pure und oData.

Also sag mir jetzt, wie sieht REST aus?

Ganz allgemein fragen Sie den Server nach bestimmten Daten oder bitten ihn, einige Daten zu speichern, und der Server antwortet auf die Anforderungen.

In Bezug auf die Programmierung gibt es einen Endpunkt (eine URL), auf den der Server wartet, um eine Anforderung zu erhalten. Wir stellen eine Verbindung zu diesem Endpunkt her und senden einige Daten über uns (denken Sie daran, REST ist zustandslos, es werden keine Daten über die Anforderung gespeichert), und der Server antwortet mit der richtigen Antwort.

Worte sind langweilig, lassen Sie mich Ihnen eine Demonstration geben. Ich werde Postman verwenden, um Ihnen die Anfrage und Antwort zu zeigen:

Die zurückgegebenen Daten befinden sich in JSON (JavaScript Object Notation) und können direkt aufgerufen werden.

Hier //official-joke-api.appspot.com/random_jokewird ein Endpunkt einer API genannt. Auf diesem Endpunkt wartet ein Server auf Anfragen wie die von uns gestellten.

Anatomie von REST:

Okay, jetzt wissen wir, dass Daten vom Client angefordert werden können und der Server angemessen reagiert. Schauen wir uns genauer an, wie eine Anfrage gebildet wird.

  1. Endpunkt : Ich habe Ihnen bereits davon erzählt. Zur Auffrischung ist dies die URL, unter der der REST-Server lauscht.
  2. Methode : Früher habe ich geschrieben, dass Sie Daten entweder anfordern oder ändern können, aber woher weiß der Server, welche Art von Operation der Client ausführen möchte? REST implementiert mehrere 'Methoden' für verschiedene Arten von Anforderungen. Die folgenden sind am beliebtesten:

    - GET : Ressource vom Server abrufen.

    - POST : Erstellen Sie eine Ressource für den Server.

    - PATCH oder PUT : Aktualisieren Sie die vorhandene Ressource auf dem Server.

    - LÖSCHEN : Löscht eine vorhandene Ressource vom Server.

  3. Header : Die zusätzlichen Details für die Kommunikation zwischen Client und Server (denken Sie daran, REST ist zustandslos). Einige der häufigsten Überschriften sind:

    Anfrage:

    - Host : Die IP des Clients (oder woher die Anfrage stammt)

    - Akzeptanzsprache : Sprache, die für den Kunden verständlich ist

    - User-Agent : Daten zu Client, Betriebssystem und Hersteller

    Antwort :

    - Status : Der Status der Anforderung oder des HTTP-Codes.

    - Inhaltstyp : Art der vom Server gesendeten Ressource.

    - set-cookie : setzt Cookies nach Server

  4. Daten : (auch als Text oder Nachricht bezeichnet) enthalten Informationen, die Sie an den Server senden möchten.

Genug mit den Details - zeig mir den Code.

Beginnen wir mit der Codierung eines REST-Service in Node. Wir werden alle Dinge implementieren, die wir oben gelernt haben. Wir werden auch ES6 + verwenden, um unseren Service einzuschreiben.

Vergewissern Sie sich , Node.JS installiert und nodeund npmsind in Ihrem Pfad zur Verfügung. Ich werde Node 12.16.2 und NPM 6.14.4 verwenden.

Erstellen Sie ein Verzeichnis rest-service-nodeund eine CD darin:

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

Initialisieren Sie das Knotenprojekt:

npm init -y

Die -yFlagge überspringt alle Fragen. Wenn Sie den gesamten Fragebogen ausfüllen möchten, führen Sie ihn einfach aus npm init.

Let's install some packages. We will be using the ExpressJS framework for developing the REST Server. Run the following command to install it:

npm install --save express body-parser

What's body-parser there for? Express, by default, is incapable of handling data sent via POST request as JSON. body-parser allows Express to overcome this.

Create a file called server.js and add the following code:

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.`); }); 

The first two lines are importing Express and body-parser.

Third line initializes the Express server and sets it to a variable called app.

The line, app.use(bodyParser.json()); initializes the body-parser plugin.

Finally, we are setting our server to listen on port 5000 for requests.

Getting data from the REST Server:

To get data from a server, we need a GET request. Add the following code before 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.

You can extend this for the remaining types of requests and even implement a full featured back-end CRUD app.

I hope you have learned something from this. If you have any questions, feel free to reach out to me over twitter! Happy Coding!