Node.js 淺談res tful

37
Node.js 淺談RESTful MiCloud - Simon Course PPT: http://goo.gl/F7ybr0

Transcript of Node.js 淺談res tful

Page 1: Node.js 淺談res tful

Node.js 淺談RESTfulMiCloud - Simon

Course PPT: http://goo.gl/F7ybr0

Page 2: Node.js 淺談res tful

● REST的基本概念● 哪些服務使用REST● REST Client

○ request● REST Server

○ restify○ express○ connect

● 更進階的模組○ rest-client○ rest-api-connector

大綱

Page 3: Node.js 淺談res tful

REST(Representational State Transfer)

從定義開始

Protocol (HTTP, HTTPS)

URI Method Parameter Header

Cache Reverse Proxy Server Pages

Resources

Page 4: Node.js 淺談res tful

REST principles

● 去服務導向(SOAP常用的資源定義方式),功能以resources(資源)方式存在

● 資源以URI(Uniform Resource Identifier)方式存在

● 所有 resources 共用一致的介面在 client 跟 resource 之間轉換狀態

● 特色○ 使用者端/伺服器端 Client/Server○ 狀態無關 Stateless○ 可以快取 Cacheable○ 分層的 Layered

● 符合 REST principles 的系統稱做 RESTful

Page 5: Node.js 淺談res tful

簡單的說

● 基於HTTP(S)實作資源導向架構● RESTful是一種寫作習慣

Page 6: Node.js 淺談res tful

Protocol / URI

Method

Parameter

Header

Body

Header

State

REST與HTTP協定的關係Request Response

Authentication

Data

Operation

Hidden Data Response

Clear Data Response

Processing Status

Location

Page 7: Node.js 淺談res tful

哪些服務使用REST

Page 8: Node.js 淺談res tful

Building a REST Client

Page 9: Node.js 淺談res tful

一個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

Page 10: Node.js 淺談res tful

一個REST Result的範例

HTTP Status Code (State)

Headers

Body

Page 11: Node.js 淺談res tful

使用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

Page 12: Node.js 淺談res tful

Building a REST Server(Case: 建立主機記憶體使用資訊REST Service)

Page 13: Node.js 淺談res tful

/** 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抓取記憶體資訊

Page 14: Node.js 淺談res tful

Connect套件

● Github:https://github.com/senchalabs/connect

Page 15: Node.js 淺談res tful

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

Page 16: Node.js 淺談res tful

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' }))

Page 17: Node.js 淺談res tful

Lab 1: Using Connect ● Input:

○ method: GET○ route: /mem

● Output: JSON

Page 18: Node.js 淺談res tful

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);

Page 19: Node.js 淺談res tful

Express模組

● Github: https://github.com/visionmedia

Page 20: Node.js 淺談res tful

Express Routing規則(1)

● app.all(route, callback)● app.get(route, callback)● app.post(route, callback)● app.put(route, callback)● app.del(route, callback)

Page 21: Node.js 淺談res tful

Express Routing規則(2)

● app.get(‘/:key’, function(req, res, next){...})● app.get(‘/:key/*’, function(req, res, next){...})

Page 22: Node.js 淺談res tful

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

Page 23: Node.js 淺談res tful

restify模組

● Github: https://github.com/mcavage● 官網:http://mcavage.me/node-restify/

Page 24: Node.js 淺談res tful

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

Page 25: Node.js 淺談res tful

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

Page 26: Node.js 淺談res tful

連線RESTful更進階(簡單)的模組

Page 27: Node.js 淺談res tful

rest-client模組

● Github: https://github.com/clonn/rest-client

Page 28: Node.js 淺談res tful

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中

Page 29: Node.js 淺談res tful

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操作實作

Page 30: Node.js 淺談res tful

rest-api-connector模組

● Github: https://github.com/peihsinsu/rest-api-connector

Page 31: Node.js 淺談res tful

rest-api-connector目的

● rest-less: 減少直接操作url fetch的動作● api to sdk: 直接使用sdk對應rest api,讓開發

者直接操作function

Page 32: Node.js 淺談res tful

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的範例 - 定義

Page 33: Node.js 淺談res tful

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

Page 34: Node.js 淺談res tful

上面範例的操作

/** 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;

Page 35: Node.js 淺談res tful

Lab 2: 使用此module建立RESTful API

● DB: dbmanager.js● Free CouchDB host: https:

//www.iriscouch.com● 目的:

○ 建置新刪改查的RESTful API

○ 建置對應的Node.js Client

Page 36: Node.js 淺談res tful

Course Sample Code Github

● https://github.com/micloud/class-nodejs-rest● Course PPT: http://goo.gl/F7ybr0

Page 37: Node.js 淺談res tful

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