Cara yang tepat untuk mengatur status respons dan konten JSON dalam API REST yang dibuat dengan simpuljs dan ekspres

187

Saya bermain-main dengan Nodejs dan mengekspresikan dengan membangun API istirahat kecil. Pertanyaan saya adalah, apa praktik terbaik / cara terbaik untuk mengatur status kode, serta data respons?

Biarkan saya jelaskan dengan sedikit kode (saya tidak akan meletakkan node dan mengungkapkan kode yang diperlukan untuk memulai server, hanya metode router yang bersangkutan):

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];
  }
};

Kode di bawah berfungsi dengan baik, dan saat mengirim permintaan dengan tukang pos, saya mendapatkan hasil berikut: masukkan deskripsi gambar di sini

Seperti yang Anda lihat, statusnya menunjukkan 200, yang OK. Tetapi apakah ini cara terbaik untuk melakukan ini? Apakah ada kasus di mana saya harus mengatur status sendiri, serta JSON yang dikembalikan? Atau apakah itu selalu ditangani dengan ekspres?

Sebagai contoh, saya baru saja membuat tes cepat dan sedikit memodifikasi metode get di atas:

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

Seperti yang Anda lihat, jika pengguna tidak ditemukan dalam array, saya hanya akan menetapkan status 404.

Sumber daya / saran untuk mempelajari lebih lanjut tentang topik ini lebih dari diterima.

adipati
sumber
3
Ini adalah jawaban berperingkat tertinggi saya dan tidak diterima :( @dukable, saya tahu ini sudah lama, tapi apakah itu menyelesaikan masalah Anda?
Michał Dudak
@ MichałDudak: Ya, jawaban Anda harus yang diterima. Tetapi pengguna adipable ini tidak aktif sejak 15 Oktober 2015 (pada 31 Jul 2017). +1 untuk jawaban Anda;)
Amol M Kulkarni

Jawaban:

230

Referensi API Express mencakup kasus ini.

Lihat status dan kirim .

Singkatnya, Anda hanya perlu memanggil statusmetode sebelum menelepon jsonatau send:

res.status(500).send({ error: "boo:(" });
Michał Dudak
sumber
32
Jika Anda hanya ingin mengirim kode status (tidak ada data), metodenya adalahres.sendStatus(400);
internet-nico
3
Ini sepertinya tidak berfungsi lagi. Tanggapan dikirim dengan kode status yang benar, tetapi tidak ada isi ....
LondonRob
2
Abaikan komentar terakhir saya. Jika Anda mengatur status ke 204 (Tidak ada konten) itu tidak mengirim tubuh.
LondonRob
2
@ internet-nico res.sendStatus(400);mengirim data string juga, setara denganres.status(400).send('Not Found')
Davide
74

Anda bisa melakukannya dengan cara ini:

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

Ini akan mengatur kode status HTTP ke 400, berfungsi bahkan dalam 4 express.

mzalazar
sumber
17
express deprecated res.json(status, obj): Use res.status(status).json(obj) instead Jadi, res.status(400).json(json_response)akan akurat saat ini.
Will Luce
Ya, terima kasih ... ini ditandai sudah usang, tetapi masih berfungsi: P Komentar Anda valid, bagus.
mzalazar
Mendukung anwer -res.status(500).send({ error: "boo:(" });
prayagupd
41

status 200 akan menjadi default saat menggunakan res.send, res.json, dll

Anda dapat mengatur status seperti res.status(500).json({ error: 'something is wrong' });

Seringkali saya akan melakukan sesuatu seperti ...

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

Kemudian minta middleware kesalahan saya mengirim respons, dan melakukan hal lain yang perlu saya lakukan ketika ada kesalahan.

Selain itu: res.sendStatus(status)telah ditambahkan pada versi 4.9.0 http://expressjs.com/4x/api.html#res.sendStatus

Jordonias
sumber
23

Daftar Kode Status HTTP

Praktik yang baik mengenai respons status adalah, dapat diprediksi, mengirim kode status HTTP yang tepat tergantung pada kesalahan (4xx untuk kesalahan klien, 5xx untuk kesalahan server), mengenai respons JSON yang sebenarnya tidak ada "alkitab" tetapi ide yang bagus adalah untuk mengirim (lagi) status dan data sebagai 2 properti berbeda dari objek root dalam respons yang berhasil (dengan cara ini Anda memberi klien kesempatan untuk menangkap status dari header HTTP dan payload itu sendiri) dan properti ke-3 yang menjelaskan kesalahan dengan cara yang bisa dipahami manusia dalam kasus kesalahan.

Stripe API berperilaku serupa di dunia nyata.

yaitu

baik

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

Kesalahan

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

Saya menggunakan ini dalam aplikasi Express.js saya:

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

Cara standar untuk mendapatkan HttpResponse penuh yang mencakup properti berikut

  1. body // berisi data Anda
  2. header
  3. baik
  4. status
  5. statusText
  6. Tipe
  7. url

Di backend , lakukan ini

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

Di Frontend misalnya dalam Angular, lakukan saja:

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)
})
WasiF
sumber
3
res.status(500).jsonp(dataRes);
Gustavo Grisales
sumber
2
try {
  var data = {foo: "bar"};
  res.json(JSON.stringify(data));
}
catch (e) {
  res.status(500).json(JSON.stringify(e));
}
Sma Ma
sumber
0

Anda bisa melakukan ini

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

Cara terbaik untuk mengirim respons kesalahan adalah return res.status(400).send({ message: 'An error has occurred' }).

Kemudian, di frontend Anda, Anda dapat menangkapnya menggunakan sesuatu seperti ini:

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

Masuk saja errtidak akan berfungsi, karena objek pesan terkirim Anda berada err.response.data.

Semoga itu bisa membantu!

Radu
sumber