Node.js dla początkujących - Część 14: Express.JS middleware

1/20/2025 Kurs JavaScript

Mateusz Kędziora

image

Witajcie w kolejnym wpisie z kursu JavaScript! Dziś zanurzymy się w fascynujący świat Express.js i poznamy dwa kluczowe pojęcia: routing i middleware. To one pozwalają nam budować rozbudowane i dynamiczne aplikacje webowe. Brzmi groźnie? Bez obaw, rozłożymy to na czynniki pierwsze!

Czym jest Express.js? Krótkie przypomnienie

Zanim przejdziemy do konkretów, małe przypomnienie. Express.js to minimalistyczna i elastyczna platforma Node.js do tworzenia aplikacji webowych. Upraszcza wiele zadań, z którymi musielibyśmy się mierzyć, pisząc kod „od zera” w czystym Node.js. Link do artykułu wstęp do Express.js

Routing: Kierowanie Ruchem w Twojej Aplikacji

Wyobraź sobie, że Twoja aplikacja webowa to miasto. Routing to system dróg i znaków drogowych, który kieruje ruch (czyli żądania od użytkowników) do odpowiednich miejsc (czyli funkcji, które te żądania obsługują).

W Express.js definiujemy routing za pomocą metod obiektu app (naszej aplikacji). Najczęściej używane metody to:

  • app.get(): Obsługuje żądania HTTP GET (np. pobieranie strony).
  • app.post(): Obsługuje żądania HTTP POST (np. wysyłanie formularza).
  • app.put(): Obsługuje żądania HTTP PUT (np. aktualizacja danych).
  • app.delete(): Obsługuje żądania HTTP DELETE (np. usuwanie danych).

Przykład:

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

app.get('/', (req, res) => {
  res.send('Witaj na stronie głównej!');
});

app.get('/o-nas', (req, res) => {
  res.send('Strona "O nas"');
});

app.post('/kontakt', (req, res) => {
  res.send('Otrzymaliśmy Twój formularz kontaktowy!');
});

app.listen(port, () => {
  console.log(`Aplikacja nasłuchuje na porcie ${port}`);
});

W powyższym przykładzie zdefiniowaliśmy trzy route:

  • /: Strona główna.
  • /o-nas: Strona „O nas”.
  • /kontakt: Obsługa formularza kontaktowego (metoda POST).

Parametry w routach

Routing pozwala również na definiowanie parametrów w adresach URL. To bardzo przydatne, gdy chcemy dynamicznie generować treść strony na podstawie danych przekazanych w adresie.

Przykład:

app.get('/uzytkownik/:id', (req, res) => {
  res.send(`Profil użytkownika o ID: ${req.params.id}`);
});

Teraz, gdy użytkownik odwiedzi adres /uzytkownik/123, zobaczy komunikat „Profil użytkownika o ID: 123”.

Routing z użyciem Routera

Dla bardziej złożonych aplikacji, warto użyć express.Router(). Pozwala to na modularne definiowanie routów.

Przykład:

const express = require('express');
const app = express();
const router = express.Router();

router.get('/', (req, res) => {
  res.send('Strona główna API');
});

router.get('/produkty', (req, res) => {
  res.send('Lista produktów');
});

app.use('/api', router); // Montujemy router pod adresem /api

app.listen(3000, () => console.log('Serwer działa na porcie 3000'));

Teraz wszystkie route zdefiniowane w router będą dostępne pod adresem /api. Na przykład, /api/produkty.

Middleware: Strażnicy Twojej Aplikacji

Middleware to funkcje, które są wykonywane pomiędzy odebraniem żądania a wysłaniem odpowiedzi. Możemy ich używać do różnych zadań, takich jak:

  • Logowanie żądań.
  • Uwierzytelnianie użytkowników.
  • Parsowanie danych (np. JSON).
  • Obsługa błędów.

Middleware w Express.js przyjmuje trzy argumenty:

  • req: Obiekt żądania.
  • res: Obiekt odpowiedzi.
  • next: Funkcja, która przekazuje sterowanie do następnego middleware lub do finalnego handlera route.

Przykład:

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

const logger = (req, res, next) => {
  console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`);
  next(); // Ważne! Przekazujemy sterowanie dalej
};

app.use(logger); // Używamy middleware dla wszystkich route

app.get('/', (req, res) => {
  res.send('Strona główna');
});

app.listen(3000, () => console.log('Serwer działa na porcie 3000'));

Teraz każde żądanie zostanie zalogowane w konsoli.

Przykłady wbudowanych middleware

Express.js dostarcza kilka wbudowanych middleware, takich jak:

  • express.json(): Parsuje dane w formacie JSON.
  • express.urlencoded(): Parsuje dane z formularzy HTML.
  • express.static(): Udostępnia pliki statyczne (np. CSS, JavaScript, obrazki).

Przykład:

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

app.use(express.json()); // Parsowanie JSON
app.use(express.urlencoded({ extended: true })); // Parsowanie danych z formularzy
app.use(express.static('public')); // Udostępnianie plików statycznych z folderu public

app.post('/dane', (req, res) => {
  console.log(req.body); // Dane z formularza lub JSON
  res.send('Dane odebrane');
});

app.listen(3000, () => console.log('Serwer działa na porcie 3000'));

Middleware na poziomie route

Możemy również stosować middleware tylko do wybranych route.

Przykład:

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

const authMiddleware = (req, res, next) => {
  // Sprawdzanie, czy użytkownik jest zalogowany
  if (req.headers.authorization === 'token') {
    next();
  } else {
    res.status(401).send('Brak autoryzacji');
  }
};

app.get('/chroniony-zasob', authMiddleware, (req, res) => {
  res.send('Dostęp do chronionego zasobu');
});

app.get('/publiczny-zasob', (req, res) => {
    res.send('Dostęp do publicznego zasobu')
})

app.listen(3000, () => console.log('Serwer działa na porcie 3000'));

Tylko użytkownicy z poprawnym tokenem w nagłówku Authorization będą mieli dostęp do route /chroniony-zasob.

Praca Domowa

  1. Stwórz aplikację Express.js, która będzie miała trzy route:
    • /: Strona główna z prostym powitaniem.
    • /produkty: Strona z listą (na razie statyczną) produktów.
    • /kontakt: Strona z formularzem kontaktowym (na razie bez obsługi wysyłania).
  2. Dodaj middleware, który będzie logował każde żądanie (metoda, URL, czas).
  3. Dodaj middleware, który będzie sprawdzał, czy w adresie URL jest parametr debug=true. Jeśli tak, to w konsoli powinna pojawić się dodatkowa informacja.

Dodatkowe zadanie dla ambitnych:

Stwórz router dla API, który będzie zawierał route do pobierania, dodawania, aktualizowania i usuwania produktów (na razie operacje na danych w pamięci).

Podsumowanie

Routing i middleware to fundamenty tworzenia aplikacji webowych w Express.js. Dają nam kontrolę nad przepływem żądań i pozwalają na dodawanie logiki do naszej aplikacji w sposób modularny i elasty

Polecane artykuły