ExpressJS - RESTFul APIs

Eine API wird immer benötigt, um mobile Anwendungen und Anwendungen mit nur einer Seite zu erstellen, AJAX-Aufrufe zu verwenden und Daten für Clients bereitzustellen. Ein beliebter Architekturstil zum Strukturieren und Benennen dieser APIs und der Endpunkte wird aufgerufenREST(Representational Transfer State). HTTP 1.1wurde unter Berücksichtigung der REST-Prinzipien entwickelt. REST wurde von eingeführtRoy Fielding im Jahr 2000 in seinen Paper Fielding Dissertations.

RESTful URIs und Methoden liefern uns fast alle Informationen, die wir zur Bearbeitung einer Anfrage benötigen. Die folgende Tabelle fasst zusammen, wie die verschiedenen Verben verwendet werden sollten und wie URIs benannt werden sollten. Wir werden gegen Ende eine Film-API erstellen. Lassen Sie uns nun diskutieren, wie es strukturiert sein wird.

Methode URI Einzelheiten Funktion
BEKOMMEN /Filme Sicher, zwischenspeicherbar Ruft die Liste aller Filme und deren Details ab
BEKOMMEN / movies / 1234 Sicher, zwischenspeicherbar Ruft die Details der Film-ID 1234 ab
POST /Filme N / A Erstellt einen neuen Film mit den angegebenen Details. Die Antwort enthält den URI für diese neu erstellte Ressource.
STELLEN / movies / 1234 Idempotent Ändert die Film-ID 1234 (erstellt eine, falls sie noch nicht vorhanden ist). Die Antwort enthält den URI für diese neu erstellte Ressource.
LÖSCHEN / movies / 1234 Idempotent Die Film-ID 1234 sollte gelöscht werden, falls vorhanden. Die Antwort sollte den Status der Anforderung enthalten.
LÖSCHEN oder EINSETZEN /Filme Ungültig Sollte ungültig sein. DELETE und PUT sollte angeben, an welcher Ressource sie arbeiten.

Lassen Sie uns diese API jetzt in Express erstellen. Wir werden JSON als Transportdatenformat verwenden, da es in JavaScript einfach zu verarbeiten ist und andere Vorteile bietet. Ersetzen Sie Ihreindex.js Datei mit dem movies.js Datei wie im folgenden Programm.

index.js

var express = require('express');
var bodyParser = require('body-parser');
var multer = require('multer');
var upload = multer();

var app = express();

app.use(cookieParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(upload.array());

//Require the Router we defined in movies.js
var movies = require('./movies.js');

//Use the Router on the sub route /movies
app.use('/movies', movies);

app.listen(3000);

Nachdem wir unsere Anwendung eingerichtet haben, konzentrieren wir uns auf die Erstellung der API.

Beginnen Sie mit dem Einrichten der Datei movies.js. Wir verwenden keine Datenbank zum Speichern der Filme, sondern speichern sie im Speicher. Bei jedem Neustart des Servers verschwinden die von uns hinzugefügten Filme. Dies kann leicht mithilfe einer Datenbank oder einer Datei (mithilfe des Knotens fs-Modul) nachgeahmt werden.

Sobald Sie Express importiert haben, erstellen Sie einen Router und exportieren Sie ihn mit module.exports -

var express = require('express');
var router = express.Router();
var movies = [
   {id: 101, name: "Fight Club", year: 1999, rating: 8.1},
   {id: 102, name: "Inception", year: 2010, rating: 8.7},
   {id: 103, name: "The Dark Knight", year: 2008, rating: 9},
   {id: 104, name: "12 Angry Men", year: 1957, rating: 8.9}
];

//Routes will go here
module.exports = router;

Routen abrufen

Definieren wir die GET-Route, um alle Filme zu erhalten -

router.get('/', function(req, res){
   res.json(movies);
});

Um zu testen, ob dies einwandfrei funktioniert, führen Sie Ihre App aus, öffnen Sie Ihr Terminal und geben Sie -

curl -i -H "Accept: application/json" -H "Content-Type: application/json" -X GET 
localhost:3000/movies

Die folgende Antwort wird angezeigt:

[{"id":101,"name":"Fight Club","year":1999,"rating":8.1},
{"id":102,"name":"Inception","year":2010,"rating":8.7},
{"id":103,"name":"The Dark Knight","year":2008,"rating":9},
{"id":104,"name":"12 Angry Men","year":1957,"rating":8.9}]

Wir haben eine Route, um alle Filme zu bekommen. Lassen Sie uns nun eine Route erstellen, um einen bestimmten Film anhand seiner ID zu erhalten.

router.get('/:id([0-9]{3,})', function(req, res){
   var currMovie = movies.filter(function(movie){
      if(movie.id == req.params.id){
         return true;
      }
   });
   if(currMovie.length == 1){
      res.json(currMovie[0])
   } else {
      res.status(404);//Set status to 404 as movie was not found
      res.json({message: "Not Found"});
   }
});

Dadurch erhalten wir die Filme gemäß der von uns angegebenen ID. Verwenden Sie den folgenden Befehl in Ihrem Terminal, um die Ausgabe zu überprüfen:

curl -i -H "Accept: application/json" -H "Content-Type: application/json" -X GET 
localhost:3000/movies/101

Sie erhalten folgende Antwort:

{"id":101,"name":"Fight Club","year":1999,"rating":8.1}

Wenn Sie eine ungültige Route besuchen, wird eine cannot GET error Wenn Sie eine gültige Route mit einer nicht vorhandenen ID besuchen, wird ein 404-Fehler ausgegeben.

Wir sind mit den GET-Routen fertig, lassen Sie uns nun zu den weitergehen POST Route.

POST Route

Verwenden Sie die folgende Route, um die POSTed Daten -

router.post('/', function(req, res){
   //Check if all fields are provided and are valid:
   if(!req.body.name ||
      !req.body.year.toString().match(/^[0-9]{4}$/g) ||
      !req.body.rating.toString().match(/^[0-9]\.[0-9]$/g)){
      
      res.status(400);
      res.json({message: "Bad Request"});
   } else {
      var newId = movies[movies.length-1].id+1;
      movies.push({
         id: newId,
         name: req.body.name,
         year: req.body.year,
         rating: req.body.rating
      });
      res.json({message: "New movie created.", location: "/movies/" + newId});
   }
});

Dadurch wird ein neuer Film erstellt und in der Filmvariablen gespeichert. Geben Sie den folgenden Code in Ihr Terminal ein, um diese Route zu überprüfen:

curl -X POST --data "name = Toy%20story&year = 1995&rating = 8.5" http://localhost:3000/movies

Die folgende Antwort wird angezeigt:

{"message":"New movie created.","location":"/movies/105"}

Führen Sie die get-Anforderung für aus, um zu testen, ob dies dem Filmobjekt hinzugefügt wurde /movies/105nochmal. Die folgende Antwort wird angezeigt:

{"id":105,"name":"Toy story","year":"1995","rating":"8.5"}

Lassen Sie uns fortfahren, um die PUT- und DELETE-Routen zu erstellen.

PUT-Route

Die PUT-Route entspricht fast der POST-Route. Wir geben die ID für das Objekt an, das aktualisiert / erstellt wird. Erstellen Sie die Route folgendermaßen.

router.put('/:id', function(req, res){
   //Check if all fields are provided and are valid:
   if(!req.body.name ||
      !req.body.year.toString().match(/^[0-9]{4}$/g) ||
      !req.body.rating.toString().match(/^[0-9]\.[0-9]$/g) ||
      !req.params.id.toString().match(/^[0-9]{3,}$/g)){
      
      res.status(400);
      res.json({message: "Bad Request"});
   } else {
      //Gets us the index of movie with given id.
      var updateIndex = movies.map(function(movie){
         return movie.id;
      }).indexOf(parseInt(req.params.id));
      
      if(updateIndex === -1){
         //Movie not found, create new
         movies.push({
            id: req.params.id,
            name: req.body.name,
            year: req.body.year,
            rating: req.body.rating
         });
         res.json({message: "New movie created.", location: "/movies/" + req.params.id});
      } else {
         //Update existing movie
         movies[updateIndex] = {
            id: req.params.id,
            name: req.body.name,
            year: req.body.year,
            rating: req.body.rating
         };
         res.json({message: "Movie id " + req.params.id + " updated.", 
            location: "/movies/" + req.params.id});
      }
   }
});

Diese Route führt die in der obigen Tabelle angegebene Funktion aus. Das Objekt wird mit neuen Details aktualisiert, falls vorhanden. Wenn es nicht existiert, wird ein neues Objekt erstellt. Verwenden Sie den folgenden Befehl zum Einrollen der Route, um die Route zu überprüfen. Dadurch wird ein vorhandener Film aktualisiert. Um einen neuen Film zu erstellen, ändern Sie einfach die ID in eine nicht vorhandene ID.

curl -X PUT --data "name = Toy%20story&year = 1995&rating = 8.5" 
http://localhost:3000/movies/101

Response

{"message":"Movie id 101 updated.","location":"/movies/101"}

Route LÖSCHEN

Verwenden Sie den folgenden Code, um eine Löschroute zu erstellen. - -

router.delete('/:id', function(req, res){
   var removeIndex = movies.map(function(movie){
      return movie.id;
   }).indexOf(req.params.id); //Gets us the index of movie with given id.
   
   if(removeIndex === -1){
      res.json({message: "Not found"});
   } else {
      movies.splice(removeIndex, 1);
      res.send({message: "Movie id " + req.params.id + " removed."});
   }
});

Überprüfen Sie die Route auf die gleiche Weise wie die anderen Routen. Nach erfolgreichem Löschen (z. B. ID 105) erhalten Sie die folgende Ausgabe:

{message: "Movie id 105 removed."}

Endlich unsere movies.js Die Datei sieht folgendermaßen aus.

var express = require('express');
var router = express.Router();
var movies = [
   {id: 101, name: "Fight Club", year: 1999, rating: 8.1},
   {id: 102, name: "Inception", year: 2010, rating: 8.7},
   {id: 103, name: "The Dark Knight", year: 2008, rating: 9},
   {id: 104, name: "12 Angry Men", year: 1957, rating: 8.9}
];
router.get('/:id([0-9]{3,})', function(req, res){
   var currMovie = movies.filter(function(movie){
      if(movie.id == req.params.id){
         return true;
      }
   });
   
   if(currMovie.length == 1){
      res.json(currMovie[0])
   } else {
      res.status(404);  //Set status to 404 as movie was not found
      res.json({message: "Not Found"});
   }
});
router.post('/', function(req, res){
   //Check if all fields are provided and are valid:
   if(!req.body.name ||
      !req.body.year.toString().match(/^[0-9]{4}$/g) ||
      !req.body.rating.toString().match(/^[0-9]\.[0-9]$/g)){
      res.status(400);
      res.json({message: "Bad Request"});
   } else {
      var newId = movies[movies.length-1].id+1;
      movies.push({
         id: newId,
         name: req.body.name,
         year: req.body.year,
         rating: req.body.rating
      });
      res.json({message: "New movie created.", location: "/movies/" + newId});
   }
});

router.put('/:id', function(req, res) {
   //Check if all fields are provided and are valid:
   if(!req.body.name ||
      !req.body.year.toString().match(/^[0-9]{4}$/g) ||
      !req.body.rating.toString().match(/^[0-9]\.[0-9]$/g) ||
      !req.params.id.toString().match(/^[0-9]{3,}$/g)){
      res.status(400);
      res.json({message: "Bad Request"});
   } else {
      //Gets us the index of movie with given id.
      var updateIndex = movies.map(function(movie){
         return movie.id;
      }).indexOf(parseInt(req.params.id));
      
      if(updateIndex === -1){
         //Movie not found, create new
         movies.push({
            id: req.params.id,
            name: req.body.name,
            year: req.body.year,
            rating: req.body.rating
         });
         res.json({
            message: "New movie created.", location: "/movies/" + req.params.id});
      } else {
         //Update existing movie
         movies[updateIndex] = {
            id: req.params.id,
            name: req.body.name,
            year: req.body.year,
            rating: req.body.rating
         };
         res.json({message: "Movie id " + req.params.id + " updated.",
            location: "/movies/" + req.params.id});
      }
   }
});

router.delete('/:id', function(req, res){
   var removeIndex = movies.map(function(movie){
      return movie.id;
   }).indexOf(req.params.id); //Gets us the index of movie with given id.
   
   if(removeIndex === -1){
      res.json({message: "Not found"});
   } else {
      movies.splice(removeIndex, 1);
      res.send({message: "Movie id " + req.params.id + " removed."});
   }
});
module.exports = router;

Dies vervollständigt unsere REST-API. Jetzt können Sie mit diesem einfachen Architekturstil und Express viel komplexere Anwendungen erstellen.