在由nodejs制作的REST API中设置响应状态和JSON内容并表达的正确方法


186

我正在玩Nodejs,并通过构建一个小的rest API来表达。我的问题是,设置代码状态以及响应数据的最佳实践/最佳方法是什么?

让我用一些代码来解释(我不会放置节点并表达启动服务器所需的代码,而只是涉及的路由器方法):

router.get('/users/:id', function(req, res, next) {
  var user = users.getUserById(req.params.id);
  res.json(user);
});


exports.getUserById = function(id) {
  for (var i = 0; i < users.length; i++) {
    if (users[i].id == id) return users[i];
  }
};

下面的代码运行完美,当与Postman发送请求时,我得到以下结果: 在此处输入图片说明

如您所见,状态显示为200,这是确定的。但这是最好的方法吗?是否需要我自己设置状态以及返回的JSON?还是总是由快递处理?

例如,我只是做了一个快速测试,并略微修改了上面的get方法:

router.get('/users/:id', function(req, res, next) {
  var user = users.getUserById(req.params.id);
  if (user == null || user == 'undefined') {
    res.status(404);
  }
  res.json(user);
});

如您所见,如果在数组中未找到该用户,则将状态设置为404。

非常欢迎您获得更多有关此主题的资源/建议。


3
这是我的收视率最高的答案,它不接受:( @dukable,我知道它已经有一段时间,但没有它解决了问题?
米哈尔Dudak

@MichałDudak:是的,您的答案应该被接受。但是,这个可删除用户自2015年10月15日(截至2017年7月31日)以来一直未激活。+1仍是您的答案;)
Amol M Kulkarni

Answers:


228

Express API参考涵盖了这种情况。

查看状态发送

简而言之,您只需要status在调用json或之前调用方法send

res.status(500).send({ error: "boo:(" });

32
如果您只想发送状态码(无数据),则方法为res.sendStatus(400);
internet-nico

3
这似乎不再起作用。响应以正确的状态码发送,但没有正文
。...– LondonRob

2
忽略我的最后评论。如果将状态设置为204(无内容),则不会发送正文。
LondonRob

2
@ internet-nico也res.sendStatus(400);发送字符串数据,等效于res.status(400).send('Not Found')
Davide

74

您可以这样进行:

res.status(400).json(json_response);

这会将HTTP状态代码设置为400,即使在express 4中也可以使用。


17
express deprecated res.json(status, obj): Use res.status(status).json(obj) instead 因此,res.status(400).json(json_response)如今是准确的。
Will Luce

是的,谢谢...它被标记为已弃用,但仍然可以使用:P您的评论是正确的,很重要。
mzalazar


41

使用,等时res.send,默认状态为200 res.json

您可以将状态设置为 res.status(500).json({ error: 'something is wrong' });

我经常会做类似...

router.get('/something', function(req, res, next) {
  // Some stuff here
  if(err) {
    res.status(500);
    return next(err);
  }
  // More stuff here
});

然后让我的错误中间件发送响应,并在发生错误时执行我需要做的其他事情。

另外:res.sendStatus(status)已从版本4.9.0 开始添加http://expressjs.com/4x/api.html#res.sendStatus


23

HTTP状态代码列表

关于状态响应的良好做法是,可以预期地根据错误发送正确的HTTP状态代码(4xx表示客户端错误,5xx表示服务器错误),关于实际的JSON响应没有“圣经”,但是一个好主意是发送(再次)状态和数据作为成功响应中根对象的2个不同属性(通过这种方式,您使客户端有机会从HTTP标头有效负载本身捕获状态)和第三个属性来说明在出现错误的情况下,以易于理解的方式显示错误。

Stripe的 API在现实世界中的行为类似。

200, {status: 200, data: [...]}

错误

400, {status: 400, data: null, message: "You must send foo and bar to baz..."}

13

我在Express.js应用程序中使用它:

app.get('/', function (req, res) {
    res.status(200).json({
        message: 'Welcome to the project-name api'
    });
});

5

获取完整的HttpResponse的标准方法,包括以下属性

  1. 正文//包含您的数据
  2. 标头
  3. 状态
  4. statusText
  5. 类型
  6. 网址

后端,执行此操作

router.post('/signup', (req, res, next) => {
    // res object have its own statusMessage property so utilize this
    res.statusText = 'Your have signed-up succesfully'
    return res.status(200).send('You are doing a great job')
})

前端,例如中Angular,只需执行以下操作:

let url = `http://example.com/signup`
this.http.post(url, { profile: data }, {
    observe: 'response' // remember to add this, you'll get pure HttpResponse
}).subscribe(response => {
    console.log(response)
})


2
try {
  var data = {foo: "bar"};
  res.json(JSON.stringify(data));
}
catch (e) {
  res.status(500).json(JSON.stringify(e));
}

0

你可以这样做

            return res.status(201).json({
                statusCode: req.statusCode,
                method: req.method,
                message: 'Question has been added'
            });

0

发送错误响应的最佳方法是 return res.status(400).send({ message: 'An error has occurred' })

然后,在您的前端中,您可以使用以下方式捕获它:

        url: your_url,
        method: 'POST',
        headers: headers,
        data: JSON.stringify(body),
    })
        .then((res) => {
            console.log('success', res);
        })
        .catch((err) => {
            err.response && err.response.data && this.setState({ apiResponse: err.response.data })
        })

err因为您发送的消息对象驻留在其中,所以仅记录将不起作用err.response.data

希望有帮助!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.