Node.js實現RESTful api,express or koa?


文章導讀:

 

一、what's RESTful API

1.1 RESTful架構

  要理解什么是RESTful API我們可以先看一下什么是RESTful架構。

  REST是Representational State Transfer的縮寫,我們可以理解為它的含義是“表現層狀態轉化”,wikipedia是這樣說的:“an architectural style that abstracts the architectural elements within a distributed hypermedia system”,這就是REST互聯網軟件的架構原則。

  我們可以說如果一個架構符合REST原則,就稱它為RESTful架構。

1.2 RESTful API

  那么回到我們的RESTful api,我們為了有一種統一的機制,方便不同的前端設備與后端進行通信於是便有了 RESTful API這一套目前比較成熟的互聯網應用程序的API設計理論。那么我們為了設計一個合理,好用的api,需要做些什么呢?簡單的說大致需要做到以下幾點:

1 1. api與用戶的通信協議總是使用HTTPs
2 2. 我們盡量將API部署在專用域名下:https://api.example.com
3 3. url中有標示api版本號的字段:https://api.example.com/v1/
4 4. 路徑帶有明確的含義:https://api.example.com/v1/animals
5 5. 明確資源的具體操作類型,使用相應的HTTP方法:GET/POST/PUT/DELETE/PATCH
6 6. api中提供過濾信息的參數:?page=2&per_page=100:指定第幾頁,以及每頁的記錄數
7 7. 請求api后服務器需要返回明確的狀態碼,如果出錯,帶有錯誤處理

  其實我們可以簡單的理解為RESTful API就是更加規范的API。

  下面我們就可以開始基於Nodejs的express和koa來實現一些例子理解下RESTful API。

二、Express RESTful API

2.1簡單的get數據庫中的數據

我們先通過一個簡單些的只get獲取數據庫中數據的例子開始:

2.1.1 准備工作:
   確認我們已經安裝了nodejs express;
 install mongodb數據庫mac;
2.1.2 先開始最簡單的例子:
  目錄結構,data是數據庫相關的目錄,我們可以先忽略掉:

  

  確保我們的package.json文件中有mongodb等依賴:

 1 {
 2   "name":"node-api",
 3   "main":"server.js",
 4   "dependencies":{
 5     "express":"~4.0.0",
 6     "mongoose":"~3.6.13",
 7     "body-parser":"~1.0.1",
 8     "morgan":"~1.5.3",
 9     "mongodb":"~2.0.33",
10     "monk":"~1.0.1"
11   }
12 }
View Code

  在server.js中定義簡單的路由和進行數據庫操作:

 1 var express = require('express');
 2 var app = express();
 3 var bodyParser = require('body-parser');
 4 var path = require('path');
 5 //database
 6 var mongo = require('mongodb');
 7 var monk = require('monk');
 8 var db = monk('localhost:27017/restdata');
 9 
10 //app.use()里面沒有函數
11 app.use(bodyParser.urlencoded({ extended : true}));
12 app.use(bodyParser.json());
13 
14 app.use(express.static(__dirname+'/public'));
15 
16 var collectorder = db.get('orderlist');
17 var collectuser = db.get('userlist');
18 
19 
20 app.get('/orders',function(req,res){
21   collectorder.find({},{limit:20},function(err,orders){
22     res.json(orders);
23   });
24 });
25 app.get('/users',function(req,res){
26   collectuser.find({},{},function(err,users){
27     res.json(users);
28   });
29 });
30 
31 app.get('/users/:name',function(req,res){
32   //var collection = db.get(req.params.name);
33   //console.log(req.params.name);
34   collectuser.find({name:req.params.name},{},function(err,docs){
35     res.json(docs);
36   });
37 });
38 
39 //客戶端通過請求adduser接口post數據進入數據庫
40 // app.post('/adduser',function(req,res){
41 //   var db = req.db;
42 //   collectuser.insert(req.body,function(err,result){
43 //     res.send(
44 //       (err == null) ? {msg:''}:{msg:err}
45 //       );
46 //   });
47 // });
48 
49 
50 
51 
52 app.listen(3000);
View Code

  數據庫操作:

1 mongod --dbpath c:\node\nodetest2\data (項目中data目標路徑)

  新開一個控制台窗口運行:

1 mongo
2 use nodetest2(意義上的數據庫名稱)
3 db.userlist.insert({'username' : 'test1','email' : 'test1@test.com','fullname' : 'Bob Smith','age' : 27,'location' : 'San Francisco','gender' : 'Male'})
4 我們可以查看[monk] 的api,查看數據庫的操作方法

  如果沒有什么問題的話,兩個控制台窗口應該是這樣的:

  運行實例: 

1 node server.js

  訪問url就可以看到我們獲取到了的數據:

  [查看項目源碼]

 

2.2 使用express實現數據交互(get/post/delete)

  實際上,我們剛才的例子並不算是一個完整的express的項目。我們只是用到了其中的幾個API。我們通過express-generator生成的express項目的腳手架應該是這個樣子的:

  

  我們可以看到入口的app.js文件,以及控制路由的routes和控制顯示的views文件夾,里面存放了jade模板的文件。很好地組織了項目的目錄。

  可以從express官方github開始,快速上手express:[expressjs].

  這里說的數據交互的例子,有個非常詳細易懂的教程:[CREATING A SIMPLE RESTFUL WEB APP WITH NODE.JS, EXPRESS, AND MONGODB]

  然而也可以直接獲取我倉庫中的項目源代碼:[RESTful API datachange]

三、KOA RESTful API

3.1 簡單get數據
  同樣,koa版本我們也從最簡單的實例開始。
  1.目錄結構,同樣,我們也先忽略跟數據庫相關的data文件夾:

  
  2.確保我們的package.json文件中依賴了koa koa-route mongoose 和monk等:

 1 {
 2   "name": "koarestapi",
 3   "version": "0.0.1",
 4   "description": "",
 5   "main": "app.js",
 6   "dependencies": {
 7     "co-body": "~0.0.1",
 8     "co-monk": "~0.0.1",
 9     "koa": "~0.1.2",
10     "koa-route": "~1.0.2",
11     "koa-router": "~2.2.0",
12     "kongo": "~0.0.3",
13     "mongoose": "~3.8.3",
14     "monk": "~0.7.1"
15   },
16   "author": "yixuan"
17 }
View Code

  3.同樣在app.js中定義koa版本的路由和簡單的數據庫操作:

 1 var koa = require('koa');
 2 var route = require('koa-route');
 3 var app = module.exports = koa();
 4 var monk = require('monk');
 5 var wrap = require('co-monk');
 6 var db = monk('localhost:27017/apitest');
 7 var books = wrap(db.get('books'));
 8 
 9 app.use(route.get('/book',list));
10 app.use(route.get('/book/:title',show));
11 
12 function *list(){
13   var res = yield books.find({});
14   this.body = res;
15 }
16 
17 function *show(){
18   title = decodeURI(title);
19   var res = yield books.find({title:title});
20   this.body = res;
21 }
22 
23 if(!module.parent) app.listen(3000);
View Code

  我們看到了generator的影子。
  4.在上面的express版本中我們使用了自己的數據庫中的數據,那么在實際的開發過程中,可能我們會想要調試本地已有的json文件中定義的數據。於是我們同樣先起來mongo:

1 mongod --dbpath ~/work/Node-KOA/koarestapi/data(我們項目目標路徑) 

  然后把數據指向項目中的json文件:

1  mongoimport --db apitest --collection books --file data.json

  注意這對json文件中的數據格式稍有要求:[mongodb可能報錯]

  5.運行實例:

1 node --harmony app.js 

  然后就可以看到我們定義在data.json中的數據了 :

 

3.2 更進一步的koa版本的restapi

   同樣的,上面只是個簡單的例子。使用koa generator-k生成的項目腳手架應該是這樣的:

  

  我們在入口文件app.js中定義基本的依賴和訪問入口處理,在controller文件夾中的index.js中定義路由操作,在view中定義頁面顯示相關。

  非常典型的MVC目錄結構。

  更加完整的koa版本的REST項目可以在這里看到:[KOA-REST]

四、express還是koa?

    我們實際動手寫過express的項目和koa的項目的話,就會有所體會,相比於koa,express做的事情要多一些,因此他的體積也相對比較大。

  在上面兩個例子中我們可以看到,在express版本的例子中我們使用它內置的路由就解決了問題,但是在KOA中我們需要額外的路由中間件,其實更准確的說,koa 內核中沒有捆綁任何中間件,連常用的 post body 解析都沒有...但這正體現出了koa的優勢,koa的體積非常小,表現力更強,它使得中間件的編寫變得更加容易。其實可以說,Koa基本上就是一個只有骨架的框架,它具有極強的拓展性,我們可以自己書寫可充用和更加符合實際業務場景的中間件,而不用妥協的使用Express自帶的中間件。Koa雖然小,但是它通過生成器(generators JavaScript 1.7新引入的,用於解決回調嵌套的方案)減少了異步回調,提高代碼的可讀性和可維護性,同時改進了錯誤處理(Express的錯誤處理方式相當糟糕)。

  同時,Koa是一個采用面向未來的ES6的框架,比如說隨處可見的generator函數。

  雖然Koa還不是那么的穩定,但是毫無疑問的它是面向未來的,下一代Nodejs框架。

  那么Koa相比於Express到底優勢體現在那些方面呢?總的來說,koa 的先天優勢在於 generator,帶來的主要好處如下:

1 更加優雅、簡單、安全的中間件機制
2 更加簡單、優雅地異常處理
3 更加優雅地異步編程方式

  這里有更加官方的說明:[Koa vs Express]

  其實,koa 與 express 是共享底層庫的,如果你會使用 express ,那么只要理解 generator 與 koa 框架 api,就可以快速上手。

  如果還沒有使用過express那么不如直接開始學習Koa,從這里開始:[koa 中文網]

五、參考資料

[install mongodb
[express Routing]
[simple restful api]
[restful web app node express mongodb]
[koa examples]
[monk api]
[理解RESTful架構]
[RESTful api設計指南]

[mongodb的一個issue]

[expressjs]

[koa 中文文檔]

[introduction to generator&koajs part1]

[introduction to generator&koajs part2]

[Node.js框架 express VS KOA]

[Koa vs Express]

 

&ps-接下來文章預告:

  yield語句與Generator函數

  KOA實踐


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM