REST是 Roy Fielding 在2000年的Paper Fielding论文中提出的,RESTful URI和方法为无涯教程提供了处理请求所需的几乎所有信息。下表列出了应如何使用各种动词以及如何命名URI,将在最后创建一个 movies API;
Method | URI | Function |
---|---|---|
GET | /movie | 获取所有电影及其详细信息的列表 |
GET | /movies/1234 | 获取电影ID 1234的详细信息 |
POST | /movies | 创建新电影。 |
PUT | /movies/1234 | 修改电影ID 1234(如果不存在则创建一个)。 |
DELETE | /movies/1234 | 电影ID 1234(如果存在)应删除。 |
现在在Express中创建此API。像下面的程序一样,将 index.js 文件替换为 movies.js 文件。
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()); //需要我们在movies.js中定义的Router var movies=require('./movies.js'); //在子路由 /movies 上使用路由器 app.use('/movies', movies); app.listen(3000);
首先设置movies.js文件,不是使用数据库来存储电影,而是将它们存储在内存中,因此,每次服务器重新启动时,添加的电影都会消失。可以使用数据库或文件(使用节点fs模块)轻松地模拟它。
导入Express之后,创建一个路由器并使用 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;
GET 路由
定义获取所有电影的GET路由-
router.get('/', function(req, res){ res.json(movies); });
要测试是否正常,请运行您的应用,然后打开终端并输入-
curl -i -H "Accept: application/json" -H "Content-Type: application/json" -X GET localhost:3000/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}]
现在让无涯教程创建一条通过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"}); } });
这将根据提供的ID获取电影。要检查输出,请在终端中使用以下命令:
curl -i -H "Accept: application/json" -H "Content-Type: application/json" -X GET localhost:3000/movies/101
您将获得以下响应-
{"id":101,"name":"Fight Club","year":1999,"rating":8.1}
POST 路由
使用以下路由来处理 POST 数据-
router.post('/', function(req, res){ //检查是否提供了所有字段并且是否有效: 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}); } });
这将创建一个新电影并将其存储在movie变量中。要检查此路由,请在终端中输入以下代码-
curl -X POST --data "name=Toy%20story&year=1995&rating=8.5" http://localhost:3000/movies
将显示以下响应-
{"message":"New movie created.","location":"/movies/105"}
要测试是否已将其添加到movie对象,请再次运行/movies/105的get请求。 将显示以下响应-
{"id":105,"name":"Toy story","year":"1995","rating":"8.5"}
PUT 路由
PUT路由与POST路由几乎相同,无涯教程将为将要updated/created的对象指定ID, 通过以下方式创建路由。
router.put('/:id', function(req, res){ //检查是否提供了所有字段并且是否有效: 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 { //获取给定 id 的电影索引。 var updateIndex=movies.map(function(movie){ return movie.id; }).indexOf(parseInt(req.params.id)); if(updateIndex === -1){ //找不到电影,新建 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 { //更新现有电影 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}); } } });
此路由将执行上表中指定的函数,如果存在,它将更新对象,如果不存在,它将创建一个新对象,要创建新的电影,只需将ID更改为不存在的ID。
curl -X PUT --data "name=Toy%20story&year=1995&rating=8.5" http://localhost:3000/movies/101
响应
{"message":"Movie id 101 updated.","location":"/movies/101"}
DELETE 路由
使用以下代码创建删除路由。 -
router.delete('/:id', function(req, res){ var removeIndex=movies.map(function(movie){ return movie.id; }).indexOf(req.params.id); //获取给定 id 的电影索引。 if(removeIndex === -1){ res.json({message: "Not found"}); } else { movies.splice(removeIndex, 1); res.send({message: "Movie id " + req.params.id + " removed."}); } });
以与检查其他路由相同的方式检查路由。成功删除后(如id 105),您将获得以下输出-
{message: "Movie id 105 removed."}
最后,无涯教程的 movies.js 文件将如下所示。
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); //由于找不到电影,因此将状态设置为 404 res.json({message: "Not Found"}); } }); router.post('/', function(req, res){ //检查是否提供了所有字段并且是否有效: 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) { //检查是否提供了所有字段并且是否有效: 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 { //检查是否提供了所有字段并且是否有效: var updateIndex=movies.map(function(movie){ return movie.id; }).indexOf(parseInt(req.params.id)); if(updateIndex === -1){ //找不到电影,新建 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 { //更新现有电影 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); //获取给定 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;
这样就完成了无涯教程的REST API。现在,您可以使用此简单的体系结构样式和Express创建更复杂的应用程序。
参考链接
https://www.learnfk.com/expressjs/expressjs-restful-apis.html