这几天一直看到 RESTful REST blahblah的资料,
但其实一直没有很明白RESTful是什么意思,因此决定透过实做来了解什么是RESTful了
首先,要来介绍什么是 REST
REST (Representational State Transfer) 中文翻译叫做「具象状态传输」,
是一种网路架构风格,目的是便于不同软体/程序在网络(例如网际网路)中互相传递信息。
-- Wikipedia
符合REST风格的Web API就被称为 RESTful API
以 API 而言,假设我们正在撰写一组待办事项的 API,
可能会有以下方式来作为 API 的 interface:获取使用者资料
若是以 REST 风格来开发 RESTful API 的话:/getAllUsers
获取使用者1号资料/getUser/1
新增使用者资料/createUser
更新使用者资料/updateUser/1
删除使用者资料/deleteUser/1
获取使用者资料
/GET /users
获取使用者1号资料/GET /user/1
新增使用者资料/POST /user
更新使用者资料/PUT /user/1
删除使用者资料/DELETE /user/1
--什么是 REST/RESTful
从这边就可以看出REST风格开发的充分利用了前面说过的HTTP method
而设计一个好的RESTful API有以下需要先了解
HTTP动词(只撷取常见的)
GET
: 读取资源PUT
: 替换资源DELETE
: 删除资源POST
: 新增资源;也作为万用动词,处理其它要求URI名词
URI由prefix + API endpoint组成,而Prefix的部份可有可无 (/api 可以省略)。
HTTP回传状态码
2xx
: 成功3xx
: 重新导向4xx
: 用户端错误(用户端不应retry原始请求)5xx
: 伺服器错误(用户端可合理retry)HTTP Header
HTTP Body: JSON或XML格式
RESTful API是一种设计风格,使API设计具有整体一致性,易于维护、扩展,且充份利用HTTP协定的特点。
-- 简明RESTful API设计要点
有个大略的了解后就开始来设计RESTful API吧!
第五个应用:製作RESTful Web API
参考来源: Build Node.js RESTful APIs in 10 Minutes
这次要来作一个简单的 ToDo List (底下的事项称作task)
建立一个待办事项(POST
): /tasks
读取一个待办事项(GET
): /tasks/:taskId
删除一个待办事项(DELETE
): /tasks/:taskId
读取整个待办事项列表(GET
): /tasks
更新一个待办事项(PUT
): /tasks/:taskId
备注
因为Web API出错时通常传回的是HTTP状态码,因此如上面所说,必须要能看懂基本的意涵。如果想让他人也能存取API的话,可以参考跨来源资源共享 (CORS) 来管理因为这次的练习牵涉到了后端,因此採用 Mongoose 来实作资料库。
Mongoos是一套给 Node.js 用的 MongoDB ODM 资料库
上述都做好后就能开始做Todo List了!
打开你的终端机,在你想要建立todoListApi资料夹的地方输入 mkdir todoListApi
前往该资料夹 cd todoListApi
如上图,我自己是建立在桌面
输入npm init
,之后会要求你输入名字、版本等讯息,
只有名字是必须输入的,其他均可以略过,我输入的名字是todolist
我们可以透过 npm init
来生成 package.json来定义相关套件,更多资讯可以点此处。
输入 touch server.js
在这个资料夹内建立 server.js
输入 mkdir api
建立一个api资料夹,并输入 mkdir api/controllers api/models api/routes
api在底下建立三个不同的资料夹(models, routes, controllers)
输入 touch api/controllers/todoListController.js api/models/todoListModel.js api/routes/todoListRoutes.js
在三个资料夹底下分别建立对应的js档(还是空的)
所以现在你的资料夹看起来像是这样
输入 npm install --save-dev nodemon
安装nodemon协助程式开发
输入 npm install express --save
输入 npm install mongoose --save
安装Mongoose
打开package.json在script的部分加上 "start": "nodemon server.js"
补充: --save-dev 和 --save的用意
做完以上步骤后就能开始打code了!
设定伺服器(Server)
先打开 server.js
贴上以下的程式码
var express = require('express'), app = express(), port = process.env.PORT || 300;app.listen(port);console.log('todo list RESTful API server started on: ' + port);
在终端机输入 npm run start
就会发现server开始运作
设定资料表格式(Schema)
打开 todoListModel.js
贴上以下的程式码
'use strict'; //未必要写var mongoose = require('mongoose'); var Schema = mongoose.Schema;//建立一个model表现collection的样子(name, Created_date, status)并规定它的格式//collection包含name:任务名字 Created_date:建立日期 status:目前状态('pending', 'ongoing', 'completed')var TaskSchema = new Schema({ name: { type: String, Required: 'Kindly enter the name of the task' }, Created_date: { type: Date, default: Date.now }, status: { type: [{ type: String, enum: ['pending', 'ongoing', 'completed'] }], default: ['pending'] }});module.exports = mongoose.model('Tasks', TaskSchema);
设定路由(Routes)
打开 todoListRoutes.js
贴上以下程式码
'use strict';module.exports = function(app) { var todoList = require('../controllers/todoListController'); // todoList Routes app.route('/tasks') .get(todoList.list_all_tasks) .post(todoList.create_a_task); app.route('/tasks/:taskId') .get(todoList.read_a_task) .put(todoList.update_a_task) .delete(todoList.delete_a_task);};
routing决定了server会如何回应HTML的请求(request)
这里有两种route(/tasks
和 /tasks/:taskId
)分别对应到不同的请求(GET/POST
和 GET/PUT/DELETE
)以及回应
设定控制器(Controller)
打开 todoListController.js
贴上以下的程式码
'use strict';var mongoose = require('mongoose'), Task = mongoose.model('Tasks'); //一开始建立的Tasks schema//针对不同request的回应(json格式)exports.list_all_tasks = function(req, res) { Task.find({}, function(err, task) { if (err) res.send(err); res.json(task); });};//CRUDexports.create_a_task = function(req, res) { var new_task = new Task(req.body); new_task.save(function(err, task) { if (err) res.send(err); res.json(task); });};exports.read_a_task = function(req, res) { Task.findById(req.params.taskId, function(err, task) { if (err) res.send(err); res.json(task); });};exports.update_a_task = function(req, res) { Task.findOneAndUpdate(req.params.taskId, req.body, { new: true }, function(err, task) { if (err) res.send(err); res.json(task); });};exports.delete_a_task = function(req, res) { Task.remove({ _id: req.params.taskId }, function(err, task) { if (err) res.send(err); res.json({ message: 'Task successfully deleted' }); });};
连接所有设定
修改 server.js
贴上以下的程式码
var express = require('express'), app = express(), port = process.env.PORT || 3000, mongoose = require('mongoose'), Task = require('./api/models/todoListModel'), bodyParser = require('body-parser');mongoose.Promise = global.Promise;mongoose.connect('mongodb://localhost/Tododb');app.use(bodyParser.urlencoded({ extended: true }));app.use(bodyParser.json());var routes = require('./api/routes/todoListRoutes');routes(app);app.listen(port);console.log('todo list RESTful API server started on: ' + port);
透过URL连接MongoDB (Tododb
)到server上
载入写好的Schema Tasks
安装、使用 bodyParser
解析回传的json资料
$ npm install --save body-parser
把之前写好的routes (todoListRoutes
)挂上server的route上
启动mongoDB (可能要在mongoDB安装处才可使用此指令)
$ mongod
假使你的mongoDB需要重新启动,输入 rs
就能重新启动了
server成功画面如上图,可以开始测试功能了
使用Postman测试操作
开启你的Postman 输入 http://localhost:3000/tasks
得到的值应该要是 [] ,因为还没有任何task被建立
动作改为 POST
,在key的部分写上name,value的部分写上task名称后送出就能新增task了
重複做多次后就如下图,使用GET
得到的就不再是[]了
要删除task的话,把动作改为 DELETE
,网址改为 http://localhost:3000/tasks/taskid
就能够成功删除
用 GET
,网址一样用 http://localhost:3000/tasks/taskid ,则是能得到单笔资料情形
以上就是简单的restful api练习!
因为感冒 + 期中考 + 作业缠身,这篇文打了好久好久好久......