Mengelola siklus hidup permintaan dengan middleware

Selesai

Tailwind Traders ingin mengamankan API web mereka. Dalam beberapa kasus, ketika permintaan mencapai aplikasi web, Anda mungkin perlu memverifikasi:

  • Autentikasi: siapa penggunanya
  • Otorisasi: apa yang diizinkan untuk dilihat atau dilakukan pengguna

Langkah-langkah permintaan

Anggap saja menangani permintaan sebagai serangkaian langkah-langkah. Jika pengguna perlu masuk untuk menangani sumber daya, langkah-langkahnya mungkin terlihat seperti ini:

  1. Praproses: Langkah opsional untuk menjalankan kode sebelum permintaan diproses.

    Contohnya adalah menentukan bahwa pengguna mengirim kredensial yang tepat melalui header permintaan. Jika kredensial diverifikasi, kirim permintaan ke langkah berikutnya. Jika pengelogan gagal, server mengembalikan respons HTTP 401.

  2. Pemrosesan: Memproses permintaan seperti berbicara dengan beberapa jenis sumber data, seperti database atau titik akhir API.

    Langkah ini menampilkan sumber daya, selama permintaan meminta sumber daya dengan benar.

  3. Postprocessing: Langkah opsional untuk menjalankan kode setelah permintaan selesai.

    Contohnya adalah mencatat hasil untuk tujuan pemantauan.

Kerangka kerja Express memiliki dukungan bawaan untuk menangani permintaan dengan cara ini. Untuk menjalankan praproses atau pemrosesan posting untuk permintaan, terapkan use() metode pada objek Express app Anda dengan formulir sintaks berikut:

app.use((req, res, next) => {})

Metode yang diteruskan ke use() metode memiliki parameter berikut:

  • req: Permintaan masuk yang berisi header permintaan dan URL panggilan. Ini mungkin juga memiliki isi data jika klien mengirim data dalam permintaan mereka.
  • res: Aliran respons yang digunakan untuk menulis informasi, seperti header dan data yang ingin Anda kirim kembali ke klien panggilan.
  • next: Fungsi middleware berikutnya dalam tumpukan. next() Jika fungsi tidak dipanggil, pemrosesan permintaan akan berhenti. Jika permintaan berhasil, Anda mungkin ingin memanggil next() untuk membuat perubahan pada respons atau mencatat hasilnya.

Alur permintaan

Jika Anda memiliki rute yang mendapat manfaat dari memiliki middleware pra atau pasca pemrosesan, siapkan fungsi dalam file kode sumber sehingga:

  • Middleware yang perlu dijalankan sebelum permintaan (pra-pemrosesan) ditentukan sebelum permintaan aktual.
  • Middleware yang perlu dijalankan setelah permintaan (postprocessing) didefinisikan setelah permintaan aktual.

Lihat contoh ini:

app.use((req, res, next) => {
  // Pre request
})
app.get('/protected-resource', () => {
  // Handle the actual request
})
app.use((req, res, next) => {
  // Post request
})

app.get('/login', () => {})

Anda juga dapat menjalankan middleware pra-pemrosesan sebagai argumen ke handler permintaan:

app.get(
  '/<some route>',
 () => {
   // Pre request middleware
 }, () => {
   // Handle the actual request
 })

Urutan fungsi middleware di Express.js sangat penting karena dijalankan secara berurutan, dalam urutan yang ditentukan dalam kode. Ini berarti bahwa jika fungsi middleware ditempatkan setelah handler rute, fungsi tersebut tidak akan dijalankan untuk rute tersebut.

Praktik terbaik manajemen rute

Berikut adalah beberapa praktik terbaik untuk mengelola urutan fungsi middleware:

  • Tempatkan middleware global di bagian atas: Fungsi middleware yang berlaku untuk semua rute harus ditempatkan di bagian atas kode Anda, sebelum penangan rute apa pun. Ini memastikan mereka dijalankan untuk setiap permintaan.

  • Memesan middleware berdasarkan kekhususan: Fungsi middleware yang lebih spesifik harus ditempatkan setelah yang lebih umum. Dengan cara ini, fungsi middleware umum dapat menangani tugas umum untuk semua rute, dan yang spesifik dapat menangani tugas untuk rute tertentu.

  • Tempatkan middleware penanganan kesalahan terakhir: Fungsi middleware dengan empat argumen diperlakukan sebagai middleware penanganan kesalahan. Mereka harus ditempatkan di akhir tumpukan middleware Anda, setelah semua middleware dan handler rute lainnya.

Berikut contohnya:

const express = require('express');
const app = express();

// Global middleware
app.use((req, res, next) => {
  console.log('This is a global middleware');
  next();
});

// Route handler
app.get('/', (req, res, next) => {
  console.log('This is a route handler');
  next();
});

// Specific middleware
app.use((req, res, next) => {
  console.log('This is a specific middleware');
  next();
});

// Error-handling middleware
app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).send('Something broke!');
});

app.listen(3000);