ExpressJS - API RESTFul
Une API est toujours nécessaire pour créer des applications mobiles, des applications monopages, utiliser les appels AJAX et fournir des données aux clients. Un style architectural populaire sur la façon de structurer et de nommer ces API et les points de terminaison est appeléREST(Representational Transfer State). HTTP 1.1a été conçu en gardant à l'esprit les principes REST. REST a été introduit parRoy Fielding en 2000 dans ses dissertations sur le terrain.
Les URI et méthodes RESTful nous fournissent presque toutes les informations dont nous avons besoin pour traiter une demande. Le tableau ci-dessous résume comment les différents verbes doivent être utilisés et comment les URI doivent être nommés. Nous créerons une API de films vers la fin; discutons maintenant de la manière dont il sera structuré.
Méthode | URI | Détails | Fonction |
---|---|---|---|
AVOIR | /films | Sûr, cachable | Obtient la liste de tous les films et leurs détails |
AVOIR | / films / 1234 | Sûr, cachable | Obtient les détails de l'ID de film 1234 |
PUBLIER | /films | N / A | Crée un nouveau film avec les détails fournis. La réponse contient l'URI de cette ressource nouvellement créée. |
METTRE | / films / 1234 | Idempotent | Modifie l'ID de film 1234 (en crée un s'il n'existe pas déjà). La réponse contient l'URI de cette ressource nouvellement créée. |
EFFACER | / films / 1234 | Idempotent | L'ID de film 1234 doit être supprimé, s'il existe. La réponse doit contenir le statut de la demande. |
SUPPRIMER ou METTRE | /films | Invalide | Doit être invalide. DELETE et PUT devrait spécifier sur quelle ressource ils travaillent. |
Créons maintenant cette API dans Express. Nous utiliserons JSON comme format de données de transport car il est facile à utiliser en JavaScript et présente d'autres avantages. Remplacez votreindex.js fichier avec le movies.js fichier comme dans le programme suivant.
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);
Maintenant que notre application est configurée, concentrons-nous sur la création de l'API.
Commencez par configurer le fichier movies.js. Nous n'utilisons pas de base de données pour stocker les films, mais les stockons en mémoire; ainsi chaque fois que le serveur redémarre, les films que nous avons ajoutés disparaissent. Cela peut facilement être imité en utilisant une base de données ou un fichier (en utilisant le module node fs).
Une fois que vous avez importé Express, créez un routeur et exportez-le en utilisant 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;
OBTENIR des itinéraires
Définissons l'itinéraire GET pour obtenir tous les films -
router.get('/', function(req, res){
res.json(movies);
});
Pour tester si cela fonctionne correctement, exécutez votre application, puis ouvrez votre terminal et entrez -
curl -i -H "Accept: application/json" -H "Content-Type: application/json" -X GET
localhost:3000/movies
La réponse suivante sera affichée -
[{"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}]
Nous avons un itinéraire pour obtenir tous les films. Créons maintenant un itinéraire pour obtenir un film spécifique par son identifiant.
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"});
}
});
Cela nous donnera les films en fonction de l'identifiant que nous avons fourni. Pour vérifier la sortie, utilisez la commande suivante dans votre terminal -
curl -i -H "Accept: application/json" -H "Content-Type: application/json" -X GET
localhost:3000/movies/101
Vous obtiendrez la réponse suivante -
{"id":101,"name":"Fight Club","year":1999,"rating":8.1}
Si vous visitez un itinéraire invalide, il produira un cannot GET error tandis que si vous visitez une route valide avec un identifiant qui n'existe pas, cela produira une erreur 404.
Nous en avons terminé avec les routes GET, passons maintenant à la POST route.
Route POST
Utilisez l'itinéraire suivant pour gérer les POSTed données -
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});
}
});
Cela créera un nouveau film et le stockera dans la variable films. Pour vérifier cet itinéraire, entrez le code suivant dans votre terminal -
curl -X POST --data "name = Toy%20story&year = 1995&rating = 8.5" http://localhost:3000/movies
La réponse suivante sera affichée -
{"message":"New movie created.","location":"/movies/105"}
Pour tester si cela a été ajouté à l'objet films, exécutez la demande d'obtention pour /movies/105encore. La réponse suivante sera affichée -
{"id":105,"name":"Toy story","year":"1995","rating":"8.5"}
Passons à la création des routes PUT et DELETE.
PUT route
La route PUT est presque la même que la route POST. Nous spécifierons l'identifiant de l'objet qui sera mis à jour / créé. Créez l'itinéraire de la manière suivante.
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});
}
}
});
Cette route exécutera la fonction spécifiée dans le tableau ci-dessus. Il mettra à jour l'objet avec de nouveaux détails s'il existe. S'il n'existe pas, il créera un nouvel objet. Pour vérifier l'itinéraire, utilisez la commande curl suivante. Cela mettra à jour un film existant. Pour créer un nouveau film, changez simplement l'identifiant en un identifiant non existant.
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"}
SUPPRIMER l'itinéraire
Utilisez le code suivant pour créer une route de suppression. -
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."});
}
});
Vérifiez l'itinéraire de la même manière que nous avons vérifié les autres itinéraires. En cas de suppression réussie (par exemple id 105), vous obtiendrez la sortie suivante -
{message: "Movie id 105 removed."}
Enfin, notre movies.js Le fichier ressemblera à ce qui suit.
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;
Ceci complète notre API REST. Vous pouvez désormais créer des applications beaucoup plus complexes en utilisant ce style architectural simple et Express.