Správa životního cyklu požadavku pomocí middlewaru

Dokončeno

Společnost Tailwind Traders chce zabezpečit své webové rozhraní API. V některých případech může být potřeba ověřit, že když požadavek dosáhne webové aplikace:

  • Ověřování: kdo je uživatel
  • Autorizace: co uživatel může zobrazit nebo dělat

Požadované kroky

Představte si zpracování požadavku jako řadu kroků. Pokud uživatel musí být k ovládání prostředku přihlášený, může postup vypadat takto:

  1. Předběžné zpracování: Volitelný krok pro spuštění kódu před zpracováním požadavku.

    Příkladem je určení, že uživatel odeslal správné přihlašovací údaje prostřednictvím hlavičky požadavku. Pokud jsou přihlašovací údaje ověřené, pošle se požadavek do dalšího kroku. Pokud se protokolování nezdaří, server vrátí odpověď HTTP 401.

  2. Zpracování: Zpracování požadavku, jako je například hovor s nějakým druhem zdroje dat, jako je databáze nebo koncový bod rozhraní API.

    Tento krok vrátí prostředek, pokud o něj požadavek správně zažádá.

  3. Postprocessing: Volitelný krok pro spuštění kódu po dokončení požadavku.

    Příkladem je protokolování výsledků pro účely monitorování.

Architektura Expressu má integrovanou podporu zpracování požadavku uvedeným způsobem. Pokud chcete pro požadavek spustit předběžné zpracování nebo následné zpracování, implementujte use() metodu v objektu Express app s následujícím formátem syntaxe:

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

Metoda předaná metodě use() má následující parametry:

  • req: Příchozí požadavek, který obsahuje hlavičky požadavku a volající adresu URL. Může mít také tělo dat, pokud klient s požadavkem odešle i data.
  • res: Stream odpovědí, který se použije k zápisu informací, jako jsou hlavičky a data, která chcete odeslat zpět volajícímu klientovi.
  • next: Další funkce middlewaru v zásobníku. next() Pokud funkce není volána, zpracování požadavku se zastaví. Pokud požadavek proběhl úspěšně, můžete volat next () a provést změny odpovědi nebo protokolovat výsledky.

Kanál požadavku

Pokud máte trasy, které mají prospěch z předzpracování nebo následného zpracování middlewaru, nastavte funkce v souboru zdrojového kódu tak, aby:

  • Middleware, který se musí spustit před definováním požadavku (předzpracováním) před vlastním požadavkem.
  • Middleware, který se musí spustit po požadavku (po zpracování), se definuje po skutečném požadavku.

Podívejte se na tento příklad:

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', () => {})

Můžete také spustit předzpracování middlewaru jako argument obslužné rutiny požadavku:

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

Pořadí funkcí middlewaru v Express.js je zásadní, protože se spouští postupně v pořadí, v jakém jsou definovány v kódu. To znamená, že pokud je funkce middlewaru umístěna po obslužné rutině trasy, nebude pro tuto trasu spuštěna.

Osvědčené postupy správy tras

Tady je několik osvědčených postupů pro správu pořadí funkcí middlewaru:

  • Umístěte globální middleware na začátek: Funkce middlewaru, které platí pro všechny trasy, by se měly umístit do horní části kódu před všemi obslužné rutiny tras. Tím se zajistí, že se pro každý požadavek spustí.

  • Řazení middlewaru podle specifikity: Konkrétnější funkce middlewaru by měly být umístěny po obecnějších funkcích. Díky tomu můžou obecné middlewarové funkce zpracovávat běžné úlohy pro všechny trasy a konkrétní úlohy pro konkrétní trasy.

  • Poslední místo middlewaru pro zpracování chyb: Funkce middlewaru se čtyřmi argumenty se považují za middleware pro zpracování chyb. Měly by být umístěny na konci zásobníku middlewaru po všech ostatních middlewarových rutinách a obslužných rutinách tras.

Tady je příklad:

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