我正在尝试使用WrongAcceptError
在node.js / restify中的RESTful API中正确处理Accept标头,如下所示。
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
因为不假定客户端理解错误消息,即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发送正确的错误状态代码和正文,或者我做错了什么?
答案 0 :(得分: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才能发送回客户端。
*/*
构造创建了一个'catch-all'格式化程序,用于Restify无法处理的所有mime类型(该列表为application/javascript
,application/json
, text/plain
和application/octet-stream
)。我可以想象,对于某些情况,全能格式化程序可能会产生问题,但这取决于您的确切设置。