Day 27: Restify —— 在Node.js中構建正確的REST Web服務

編者注:咱們發現了有趣的系列文章《30天學習30種新技術》,正在翻譯,一天一篇更新,年終禮包。下面是第 27 天的內容。java


今天決定學一個叫作restify的Node.js模塊。restify模塊使得在Node.js中寫正確的REST API變得容易了不少,並且它還提供了即裝即用的支持,如版本控制、錯誤處理、CORS和內容協商。它大量地借鑑了Express(故意地),由於這或多或少是事實上的API來寫在node.js上寫web應用程序,將數據存儲在MongoDB中。node

Restify準備

Restify須要NodeJS和NPM包管理器,這個能夠是隨node.js安裝時默認的。若是已經安裝了node.js和NPM,就能夠用NPM系統來安裝Harp了。mysql

此應用程序使用MongoDB做數據存儲。git

Restify安裝

在任何方便的目錄中的文件系統上建立一個新的目錄:github

$ mkdir myapp
$ cd myapp

輸入下面命令,安裝restify模塊:web

$ npm install restify

使用MongoJS做爲MongoDB的驅動程序,輸入下面命令安裝mongojs模塊:sql

$ npm install mongojs

編寫基於REST的API

如今已經安裝了restify和mongojs建立一個名爲app.js的新文件:mongodb

$ touch app.js

把下面內容粘貼進app.js:數據庫

var restify = require('restify');
var mongojs = require("mongojs");

這是加載restify和mongojs模塊,並給它們分配變量。express

如今,建立一個使用restify API的新服務器:

var restify = require('restify');
var mongojs = require("mongojs");

var ip_addr = '127.0.0.1';
var port    =  '8080';

var server = restify.createServer({
    name : "myapp"
});

server.listen(port ,ip_addr, function(){
    console.log('%s listening at %s ', server.name , server.url);
});

createServer() 函數接受一個選擇對象,將myapp做爲選擇對象的服務器的名稱傳遞給它,也能夠在這份文檔中查看選項的完整的選項列表。建立服務器實例以後,經過端口、ip地址和一個回調函數調用listen函數。

運行程序:

$ node app.js

而後會看見以下命令行:

myapp listening at http://127.0.0.1:8080

配置插件

restify模塊有不少內置的插件,把下面內容複製並粘貼到app.js,應該加在server.listen() 函數前面。請參閱這份文檔以瞭解全部被支持的插件。

server.use(restify.queryParser());
server.use(restify.bodyParser());
server.use(restify.CORS());

上述代碼表示:

  1. restify.queryParser() 插件是用來解析HTTP查詢字符串(如 /jobs?skills=java,mysql),解析後的內容將會在req.query裏可用。
  2. restify.bodyParser() 會在服務器上自動將請求數據轉換爲JavaScript對象。
  3. restify.CORS() 配置應用程序中的CORS支持。

MongoDB的配置

在添加路由以前,添加代碼來鏈接到MyApp的MongoDB數據庫:

var connection_string = '127.0.0.1:27017/myapp';
var db = mongojs(connection_string, ['myapp']);
var jobs = db.collection("jobs");

如今,已經鏈接到本地MongoDB實例。接下來,須要獲得使用數據庫對象的工做集合。

寫CRUD API

如今,服務器和數據庫已經準備了。仍然須要路由來定義API的行爲,複製並粘貼如下代碼到app.js文件中:

var PATH = '/jobs'
server.get({path : PATH , version : '0.0.1'} , findAllJobs);
server.get({path : PATH +'/:jobId' , version : '0.0.1'} , findJob);
server.post({path : PATH , version: '0.0.1'} ,postNewJob);
server.del({path : PATH +'/:jobId' , version: '0.0.1'} ,deleteJob);

上述代碼執行如下操做:

  1. 當用戶發出一個GET請求到'/jobs',findAllJobs回調函數將被調用。
  2. 當用戶發出一個GET請求到'/ jobs/123',findJob回調函數將被調用。
  3. 當用戶發出POST請求'/jobs',postNewJob回調函數將被調用。
  4. 當用戶刪除請求'/ jobs/123',deleteJob回調會被調用(此處原文有誤)。

如今編寫回調函數,複製並粘貼進app.js:

function findAllJobs(req, res , next){
    res.setHeader('Access-Control-Allow-Origin','*');
    jobs.find().limit(20).sort({postedOn : -1} , function(err , success){
        console.log('Response success '+success);
        console.log('Response error '+err);
        if(success){
            res.send(200 , success);
            return next();
        }else{
            return next(err);
        }

    });

}

function findJob(req, res , next){
    res.setHeader('Access-Control-Allow-Origin','*');
    jobs.findOne({_id:mongojs.ObjectId(req.params.jobId)} , function(err , success){
        console.log('Response success '+success);
        console.log('Response error '+err);
        if(success){
            res.send(200 , success);
            return next();
        }
        return next(err);
    })
}

function postNewJob(req , res , next){
    var job = {};
    job.title = req.params.title;
    job.description = req.params.description;
    job.location = req.params.location;
    job.postedOn = new Date();

    res.setHeader('Access-Control-Allow-Origin','*');

    jobs.save(job , function(err , success){
        console.log('Response success '+success);
        console.log('Response error '+err);
        if(success){
            res.send(201 , job);
            return next();
        }else{
            return next(err);
        }
    });
}

function deleteJob(req , res , next){
    res.setHeader('Access-Control-Allow-Origin','*');
    jobs.remove({_id:mongojs.ObjectId(req.params.jobId)} , function(err , success){
        console.log('Response success '+success);
        console.log('Response error '+err);
        if(success){
            res.send(204);
            return next();      
        } else{
            return next(err);
        }
    })

}

使用curl測試Web服務,輸入下面命令建立一個「job」:

$ curl -i -X POST -H "Content-Type: application/json" -d '{"title":"NodeJS Developer Required" , "description":"NodeJS Developer Required" , "location":"Sector 30, Gurgaon, India"}' http://127.0.0.1:8080/jobs

找到全部的「jobs」:

$ curl -is http://127.0.0.1:8080/jobs
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Type: application/json
Content-Length: 187
Date: Sun, 24 Nov 2013 16:17:27 GMT
Connection: keep-alive

[{"title":"NodeJS Developer Required","description":"NodeJS Developer Required","location":"Sector 30, Gurgaon, India","postedOn":"2013-11-24T16:16:16.688Z","_id":"52922650aab6107320000001"}]

部署到雲端

在應用程序部署到OpenShift以前,座如下幾個設置:

  1. 註冊一個OpenShift賬戶,它是徹底免費的,能夠分配給每一個用戶1.5 GB的內存和3 GB的磁盤空間。
  2. 安裝RHC客戶端工具,須要有ruby 1.8.7或更新的版本,若是已經有ruby gem,輸入 sudo gem install rhc ,確保它是最新版本。要更新RHC的話,執行命令 sudo gem update rhc,如需其餘協助安裝RHC命令行工具,請參閱該頁面: https://www.openshift.com/developers/rhc-client-tools-install
  3. 經過 rhc setup 命令設置您的OpenShift賬戶,此命令將幫助你建立一個命名空間,並上傳你的SSH keys到OpenShift服務器。

設置完成後,輸入如下命令建立一個新的OpenShift應用程序:

$ rhc create-app day27demo nodejs-0.10 mongodb-2 --from-code https://github.com/shekhargulati/day27-restify-openshift-demo.git

它會完成全部的工做,從建立一個應用程序、創建公共DNS、建立私有的git倉庫到最後使用代碼從Github資源庫部署應用程序。該應用程序能夠在這裏訪問 http:// day27demo-{domain-name}.rhcloud.com//

今天就這些,歡迎反饋。


原文 Day 27: Restify--Build Correct REST Web Services in Node.js
翻譯整理 SegmentFault

相關文章
相關標籤/搜索