Transcript
● REST的基本概念● 哪些服務使用REST● REST Client
○ request● REST Server
○ restify○ express○ connect
● 更進階的模組○ rest-client○ rest-api-connector
大綱
REST(Representational State Transfer)
從定義開始
Protocol (HTTP, HTTPS)
URI Method Parameter Header
Cache Reverse Proxy Server Pages
Resources
REST principles
● 去服務導向(SOAP常用的資源定義方式),功能以resources(資源)方式存在
● 資源以URI(Uniform Resource Identifier)方式存在
● 所有 resources 共用一致的介面在 client 跟 resource 之間轉換狀態
● 特色○ 使用者端/伺服器端 Client/Server○ 狀態無關 Stateless○ 可以快取 Cacheable○ 分層的 Layered
● 符合 REST principles 的系統稱做 RESTful
簡單的說
● 基於HTTP(S)實作資源導向架構● RESTful是一種寫作習慣
Protocol / URI
Method
Parameter
Header
Body
Header
State
REST與HTTP協定的關係Request Response
Authentication
Data
Operation
Hidden Data Response
Clear Data Response
Processing Status
Location
哪些服務使用REST
Building a REST Client
一個REST Call的範例
curl -i -k \
-H 'x-Api-version:~6.5' \
-u 'account:password' \
https://api.micloud.tw/account/datasets \
-X GET
Sepcify the API version
Sepcify the username and password info
API route for action
API route method
一個REST Result的範例
HTTP Status Code (State)
Headers
Body
使用Node.js進行REST call
/** sample-request.js **/var request = require('request');var account = process.argv[2], password = process.argv[3];request({ method: 'GET', url: 'https://api.micloud.tw/'+account+'/datasets', auth: { username: account, password: password }}, function(e,r,d){ if(e) console.log(e); console.log(d);});
Sepcify the username and password info
API route for action
API route method
Building a REST Server(Case: 建立主機記憶體使用資訊REST Service)
/** memory.js **/var os = require('os');function curr(){ return { free: os.freemem(), total: os.totalmem(), usage: (1 - os.freemem()/os.totalmem()) }}exports.curr = curr;
準備:透過Node.js抓取記憶體資訊
Connect套件
● Github:https://github.com/senchalabs/connect
var connect = require('connect') , http = require('http');
var app = connect();app.use(connect.bodyParser())app.use(function(req, res){ if(req.url == '/hello') res.end('Hello from Connect!\n' + JSON.stringify(req.body) || ''); else res.end('Other from Connect!\n');});
http.createServer(app).listen(3000);
Connect範例
使用bodyParser之後,則可以從 req中取到body
Connect Middleware支援
● Enable loggerapp.use(connect.logger('dev'))
● Enable static contentapp.use(connect.static('public'))app.use(connect.directory('public'))
● Enable body parserapp.use(connect.bodyParser())
● Enable cookie parserapp.use(connect.cookieParser())
● Enable sessionapp.use(connect.session({ secret: 'my secret here' }))
Lab 1: Using Connect ● Input:
○ method: GET○ route: /mem
● Output: JSON
ANS:var connect = require('connect') , http = require('http') , mem = require('./memory');var app = connect();app.use(connect.bodyParser())app.use(function(req, res){ if(req.url == '/mem' && req.method == 'GET') res.end(JSON.stringify(mem.curr())); else{ res.statusCode = 404; res.end('Page not found!'); }});http.createServer(app).listen(3000);
Express模組
● Github: https://github.com/visionmedia
Express Routing規則(1)
● app.all(route, callback)● app.get(route, callback)● app.post(route, callback)● app.put(route, callback)● app.del(route, callback)
Express Routing規則(2)
● app.get(‘/:key’, function(req, res, next){...})● app.get(‘/:key/*’, function(req, res, next){...})
Express的範例
app.get('/:type', function(req, res){ if(req.params.type == 'mem') res.end(JSON.stringify(mem.curr())); else res.send(404, 'Page not found!');});
sample-express.js
restify模組
● Github: https://github.com/mcavage● 官網:http://mcavage.me/node-restify/
restify功能
● Server API● Creating a Server● Common handlers: server.use()● Routing● Content Negotiation● Error handling● Socket.IO● Server API● Bundled Plugins● Request API● Response API● DTrace
● Client API● JsonClient● StringClient● HttpClient
restify的範例
/** sample-restify.js **/var mem = require('./memory') , server = require('restify').createServer();server.get('/:type', function (req, res, next) { if(req.params.type == 'mem') res.send(mem.curr()); else { res.statusCode = 404; res.end('Page not found!'); }});server.listen(3000, function() { console.log('%s listening at %s', server.name, server.url);});
status code rewrite
連線RESTful更進階(簡單)的模組
rest-client模組
● Github: https://github.com/clonn/rest-client
rest-client的範例
/** sample-rest-client.js **/var rc = require('rest-client');
// default value is 'GET'// Send by URL objectrc.send( { url: 'http://127.0.0.1/URL', method: 'GET' }, function (res) { console.log(res.body);});
統一操作function
統一傳入參數位置
統一callback回傳,將訊息包裝在res中
Builder Pattern Support
/** sample-rest-client2.js **/var rc = require('rest-client');rc.send({ url: 'http://odf.my.micloud.twX/odf/datasets', method: 'GET' }, function (r, body) { console.log('response>>' + r.body); }) .error(function (err) { console.log('error>>'); console.log(err);});
可串接相關操作,例如 error,讓錯誤的部份由此處的callback來操作
非error的操作,將由內建callback操作實作
rest-api-connector模組
● Github: https://github.com/peihsinsu/rest-api-connector
rest-api-connector目的
● rest-less: 減少直接操作url fetch的動作● api to sdk: 直接使用sdk對應rest api,讓開發
者直接操作function
Server: http://odf.my.micloud.twAuth: Authorization:demo● [GET]/odf/datasets
● Deacription: 取出所有既存Dataset名稱
● [GET]/odf/:ds_name/:type● Param:
○ ds_name: 資料檔名稱
○ type: page | json | download | field● Body:
○ fields (option): 資料欄位列表
● Description: 取出資料
○ Example: curl $SERVER/odf/GetAnimals/json -X GET -d fields=Name,Sex,Age
rest-api-connector的範例 - 定義
rest-api-connector的範例
/** sample-rest-api-connector **/var api = require('rest-api-connector').api;api.buildFromJson( { //define the api connection info API_CFG: { BASE_URL: "http://odf.my.micloud.tw" } // API Server URL }, { //define the api definition listDatasets: { url:"/odf/datasets", method: "GET" } });module.exports = api;
Operation Unit
api function名稱
api 定義:● url:該資源的路徑,可使用 :key讓前端帶入查詢
值。● method: 操作REST時要使用哪種http method● input:如果Route有使用:key的方式帶入值,需
要在input區域定義● 其他參數:output, validator, descript
Connect Config
上面範例的操作
/** sample-use-rest-api-connector.js **/var api = require('./sample-rest-api-connector');
api.listDatasets(function(e,r,d){ if(e) console.log(e); console.log(d);});
/** sample-rest-api-connector **/
var api = require('rest-api-connector').api;
api.buildFromJson(
{...},
{ //define the api definition
listDatasets: {
url:"/odf/datasets",
method: "GET"
}
}
);
module.exports = api;
Lab 2: 使用此module建立RESTful API
● DB: dbmanager.js● Free CouchDB host: https:
//www.iriscouch.com● 目的:
○ 建置新刪改查的RESTful API
○ 建置對應的Node.js Client
Course Sample Code Github
● https://github.com/micloud/class-nodejs-rest● Course PPT: http://goo.gl/F7ybr0
Reference● Google talk about REST: http://www.youtube.com/watch?
v=YCcAE2SCQ6k● REST 以及 REST 與 HTTP 的關係:
http://sls.weco.net/keywords/rest● 什麼是REST跟RESTful?
http://ihower.tw/blog/archives/1542● RESTful 介面實作示範
http://blog.roodo.com/rocksaying/archives/10568163.html
top related