ExpressJS - API RESTFul
È sempre necessaria un'API per creare applicazioni mobili, applicazioni a pagina singola, utilizzare chiamate AJAX e fornire dati ai client. Viene chiamato uno stile architettonico popolare su come strutturare e denominare queste API e gli endpointREST(Representational Transfer State). HTTP 1.1è stato progettato tenendo presenti i principi REST. REST è stato introdotto daRoy Fielding nel 2000 nelle sue tesi di Paper Fielding.
Gli URI ei metodi RESTful ci forniscono quasi tutte le informazioni necessarie per elaborare una richiesta. La tabella riportata di seguito riassume come i vari verbi dovrebbero essere usati e come dovrebbero essere nominati gli URI. Creeremo un'API per i film verso la fine; parliamo ora di come sarà strutturato.
Metodo | URI | Dettagli | Funzione |
---|---|---|---|
OTTENERE | /film | Sicuro, rimovibile | Ottiene l'elenco di tutti i film e i relativi dettagli |
OTTENERE | / movies / 1234 | Sicuro, rimovibile | Ottiene i dettagli dell'id del film 1234 |
INVIARE | /film | N / A | Crea un nuovo film con i dettagli forniti. La risposta contiene l'URI per questa risorsa appena creata. |
METTERE | / movies / 1234 | Idempotente | Modifica l'ID del film 1234 (ne crea uno se non esiste già). La risposta contiene l'URI per questa risorsa appena creata. |
ELIMINA | / movies / 1234 | Idempotente | L'ID film 1234 dovrebbe essere eliminato, se esistente. La risposta dovrebbe contenere lo stato della richiesta. |
CANCELLA o Metti | /film | Non valido | Non dovrebbe essere valido. DELETE e PUT dovrebbe specificare su quale risorsa stanno lavorando. |
Creiamo ora questa API in Express. Utilizzeremo JSON come formato dei dati di trasporto poiché è facile da utilizzare in JavaScript e offre altri vantaggi. Sostituisci il tuoindex.js file con l'estensione movies.js file come nel seguente programma.
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);
Ora che abbiamo configurato la nostra applicazione, concentriamoci sulla creazione dell'API.
Inizia impostando il file movies.js. Non stiamo usando un database per archiviare i film ma li stiamo archiviando in memoria; quindi ogni volta che il server si riavvia, i filmati aggiunti da noi svaniranno. Questo può essere facilmente imitato usando un database o un file (usando il modulo node fs).
Dopo aver importato Express, crea un router ed esportalo utilizzando 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;
OTTIENI percorsi
Definiamo il percorso GET per ottenere tutti i film -
router.get('/', function(req, res){
res.json(movies);
});
Per verificare se funziona correttamente, esegui l'app, quindi apri il terminale e inserisci -
curl -i -H "Accept: application/json" -H "Content-Type: application/json" -X GET
localhost:3000/movies
Verrà visualizzata la seguente risposta:
[{"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}]
Abbiamo un percorso per ottenere tutti i film. Creiamo ora un percorso per ottenere un film specifico dal suo ID.
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"});
}
});
Questo ci porterà i film in base all'ID che abbiamo fornito. Per controllare l'output, usa il seguente comando nel tuo terminale:
curl -i -H "Accept: application/json" -H "Content-Type: application/json" -X GET
localhost:3000/movies/101
Riceverai la seguente risposta:
{"id":101,"name":"Fight Club","year":1999,"rating":8.1}
Se visiti un percorso non valido, produrrà un file cannot GET error mentre se visiti un percorso valido con un id che non esiste, produrrà un errore 404.
Abbiamo finito con le rotte GET, passiamo ora alle rotte POST itinerario.
POST percorso
Usa il percorso seguente per gestire il file POSTed dati -
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});
}
});
Questo creerà un nuovo film e lo memorizzerà nella variabile movies. Per controllare questo percorso, inserisci il seguente codice nel tuo terminale:
curl -X POST --data "name = Toy%20story&year = 1995&rating = 8.5" http://localhost:3000/movies
Verrà visualizzata la seguente risposta:
{"message":"New movie created.","location":"/movies/105"}
Per verificare se questo è stato aggiunto all'oggetto film, eseguire la richiesta get per /movies/105ancora. Verrà visualizzata la seguente risposta:
{"id":105,"name":"Toy story","year":"1995","rating":"8.5"}
Passiamo ora alla creazione delle rotte PUT e DELETE.
PUT percorso
Il percorso PUT è quasi lo stesso del percorso POST. Specificheremo l'ID per l'oggetto che verrà aggiornato / creato. Crea il percorso nel modo seguente.
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});
}
}
});
Questo percorso eseguirà la funzione specificata nella tabella sopra. Aggiornerà l'oggetto con nuovi dettagli se esiste. Se non esiste, creerà un nuovo oggetto. Per controllare il percorso, utilizzare il seguente comando curl. Questo aggiornerà un film esistente. Per creare un nuovo film, cambia semplicemente l'ID in un ID non esistente.
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"}
ELIMINA percorso
Usa il codice seguente per creare un percorso di eliminazione. -
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."});
}
});
Controlla il percorso nello stesso modo in cui abbiamo controllato gli altri percorsi. In caso di eliminazione riuscita (ad esempio ID 105), otterrai il seguente output:
{message: "Movie id 105 removed."}
Infine, il nostro movies.js il file sarà simile al seguente.
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;
Questo completa la nostra API REST. Ora puoi creare applicazioni molto più complesse utilizzando questo semplice stile architettonico ed Express.