2013-04-02 3 views
0

Я пытаюсь правильно обрабатывать заголовки Accept в RESTful API в node.js/restify, используя WrongAcceptError следующим образом.Обработка Принимать заголовки в 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 

потому что клиент не считается un понимания всего сообщение об ошибке, которое в формате 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

Проблема в том, что вы возвращаете объект JSON с типом контента (application/vnd.me.org.api+json), который Restify не знает (и, следовательно, создает ошибку 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, прежде чем он может быть отправлен обратно клиенту.

*/* конструкция создает «кетчуп все» форматера, который используется для всех MIME-типов, которые Restify не может справиться сам (что список application/javascript, application/json, text/plain и application/octet-stream). Я могу себе представить, что в некоторых случаях ловушка-форматинг может создавать проблемы, но это зависит от вашей точной настройки.

+0

Причина, по которой я не использую форматировщики, состоит в том, что у меня есть несколько разных типов MIME; используя одну функцию 'reply', как указано выше, мне не нужно перечислять их все. В любом случае, мой вопрос действительно последний: как обрабатывать клиента, который принимает только неизвестные типы MIME? –

+0

Я отредактировал свой ответ, кажется, что у Рестификатора * есть * есть понятие уловить все форматирование. – robertklep

Смежные вопросы