2013-04-02 44 views
0

我想通過使用WrongAcceptError來正確處理node.js/restify中的RESTful API中的Accept標頭,如下所示。處理Node.js中的接受標題restify

var restify = require('restify') 
    ; server = restify.createServer() 

// Write some content as JSON together with appropriate HTTP headers. 
function respond(status,response,contentType,content) 
{ var json = JSON.stringify(content) 
; response.writeHead(status, 
    { 'Content-Type': contentType 
    , 'Content-Encoding': 'UTF-8' 
    , 'Content-Length': Buffer.byteLength(json,'utf-8') 
    }) 
; response.write(json) 
; response.end() 
} 

server.get('/api',function(request,response,next) 
{ var contentType = "application/vnd.me.org.api+json" 
; var properContentType = request.accepts(contentType) 
; if (properContentType!=contentType) 
    { return next(new restify.WrongAcceptError("Only provides "+contentType)) } 
    respond(200,response,contentType, 
    { "uri": "http://me.org/api" 
    , "users": "/users" 
    , "teams": "/teams" 
    }) 
    ; return next() 
}); 

server.listen(8080, function(){}); 

如果客戶端提供了合適的Accept頭,或沒有頭爲在這裏看到的正常工作:

$ curl -is http://localhost:8080/api 
HTTP/1.1 200 OK 
Content-Type: application/vnd.me.org.api+json 
Content-Encoding: UTF-8 
Content-Length: 61 
Date: Tue, 02 Apr 2013 10:19:45 GMT 
Connection: keep-alive 

{"uri":"http://me.org/api","users":"/users","teams":"/teams"} 

的問題是,如果客戶端確實提供了錯誤的Accept頭,服務器不會發送錯誤消息:

$ curl -is http://localhost:8080/api -H 'Accept: application/vnd.me.org.users+json' 
HTTP/1.1 500 Internal Server Error 
Date: Tue, 02 Apr 2013 10:27:23 GMT 
Connection: keep-alive 
Transfer-Encoding: chunked 

因爲不假設客戶端聯合國derstand錯誤信息,這是JSON,因爲 此看到:

$ curl -is http://localhost:8080/api -H 'Accept: application/json' 
HTTP/1.1 406 Not Acceptable 
Content-Type: application/json 
Content-Length: 80 
Date: Tue, 02 Apr 2013 10:30:28 GMT 
Connection: keep-alive 

{"code":"WrongAccept","message":"Only provides application/vnd.me.org.api+json"} 

所以我的問題是,如何強制restify送回到正確的錯誤狀態代碼和身體,還是我做錯事?

回答

3

問題是,您正在返回一個帶有Restify不知道的內容類型(application/vnd.me.org.api+json)的JSON對象(因此會創建一個錯誤no formatter found)。

你需要告訴你的RESTify迴應應該如何格式化:

server = restify.createServer({ 
    formatters : { 
    '*/*' : function(req, res, body) { // 'catch-all' formatter 
     if (body instanceof Error) { // see text 
     body = JSON.stringify({ 
      code : body.body.code, 
      message : body.body.message 
     }); 
     }; 
     return body; 
    } 
    } 
}); 

body instanceof Error也是必需的,因爲它必須被轉換成JSON,纔可以被髮送回客戶端。

*/*結構能產生一個「包羅萬象的」格式,這是用來爲的RESTify不能處理本身所有的MIME類型(該列表是application/javascriptapplication/jsontext/plainapplication/octet-stream)。我可以想象,在某些情況下,通用格式化程序可能會造成問題,但這取決於您的確切設置。

+0

我沒有使用格式化程序的原因是我有許多不同的MIME類型;通過使用上面的單個「響應」函數,我不必列舉所有這些函數。無論如何,我的問題確實是後者:我如何處理只接受未知MIME類型的客戶端? –

+0

我編輯了我的答案,似乎Restify *確實擁有全面格式化的概念。 – robertklep