Правильний спосіб встановити статус відповіді та вміст JSON в API REST, зроблений за допомогою nodejs та express


187

Я граю з Nodejs і висловлюю, будуючи невеликий 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? Або це завжди обробляється експресом?

Наприклад, я просто зробив швидкий тест і трохи змінив метод отримання вище:

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, я знаю, минув час, але чи вирішив це питання?
Michał Dudak

@ MichałDudak: Так, ваша відповідь має бути прийнятою. Але цей пластовий користувач не активний з 15 жовтня 2015 року (станом на 31 липня 2017 року). +1 за вашу відповідь у будь-якому випадку;)
Amol M Kulkarni

Відповіді:


230

Експрес-посилання API охоплює цей випадок.

Перегляньте стан та надішліть .

Коротше кажучи, вам просто потрібно викликати statusметод перед викликом jsonабо send:

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

32
Якщо ви хочете лише надіслати код статусу (немає даних), методом було бres.sendStatus(400);
internet-nico

3
Схоже, це вже не працює. Відповідь надсилається з правильним кодом статусу, але немає тіла ....
LondonRob

2
Ігноруй мій останній коментар. Якщо ви встановите статус 204 (Без вмісту), він не надсилатиме тіло.
LondonRob

2
@ Інтернет-Nico res.sendStatus(400);відправити рядок даних теж еквівалентноres.status(400).send('Not Found')
Давиде

74

Ви можете це зробити так:

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

Це встановить код статусу HTTP на 400, він працює навіть у експресі 4.


17
express deprecated res.json(status, obj): Use res.status(status).json(obj) instead Отже, res.status(400).json(json_response)було б точно зараз.
Буде Люс

Так, дякую ... він позначений як застарілий, але все ще працює: P Ваш коментар дійсний, хороший пункт.
mzalazar


41

статус 200 буде за замовчуванням при використанні res.send, 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 та самого корисного навантаження) та 3-го властивості, що пояснює помилка, зрозуміла людині, у випадку помилки.

API Stripe поводиться аналогічно в реальному світі.

тобто

гаразд

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. body // містить ваші дані
  2. заголовки
  3. гаразд
  4. статус
  5. statusText
  6. тип
  7. URL

У бекенд зробіть це

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')
})

На Frontend, наприклад 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(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.

Сподіваюся, що це допомагає!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.