Middleware
Middleware
MIDDLEWARE czyli oprogramowanie pośredniczące jest to rodzaj oprogramowania/funkcji umożliwiającej komunikację pomiędzy różnymi aplikacjami, usługami lub systemami.
middleware
middleware
app
REQUEST
RESPONSE
ExpressJS - Middleware
Middleware w Express pełni rolę pośrednią przed wykonaniem odpowiedniej instrukcji dla danej ścieżki.
W funkcji mamy dostęp do żądania i odpowiedzi HTTP oraz funkcji callback next, która odpowiada za wywołanie kolejnego middleware lub przejścia do odpowiedniej instrukcji dla danej ścieżki.
ExpressJS - Middleware
Funkcje middleware mogą wykonywać następujące zadania:
- wykonać dowolny kod
- wprowadzić zmiany w obiektach żądań i odpowiedzi
- zakończyć żadanie
- wywołac następne oprogramowanie pośrednie w stosie
Konstrukcja middleware
const express = require('express');
const app = express();
const customMiddleware = (req, res, next) => {
// some logic ...
next();
};
app.use(customMiddleware);
app.listen(4500, () => console.log('server started'));Zapamiętać!
Jeżeli middleware nie kończy żądania/odpowiedzi, musi zostać wywyłana funkcja next(), aby przekazać sterowanie do następnej funkcji oprogramowania pośredniego.
W przeciwnym wypadku żądanie zostanie zawieszone.
Przykład
// ...
const timeMiddleware = (req, res, next) => {
req.requestTime = new Date();
next();
};
app.use(timeMiddleware);
app.get('/', (req, res) => {
res.send('request time: ' + req.requestTime);
});
// ...Typy middleware
W Express możemy wykorzystać takie typy middleware jak:
APPLICATION-LEVEL MIDDLEWARE
Powiązanie oprogramowania warstwy pośredniej na poziomie aplikacji.
Ten rodzaj middleware będzie wykonywał się dla całej aplikacji lub dla wydzielonej grupy ścieżek.
Przykład
const express = require('express');
const app = express();
app.use((req, res, next) => {
console.log('current time', new Date());
next();
});
app.listen(4500, () => console.log('server started'));Przykład ze ścieżką
const express = require('express');
const app = express();
app.use('/user', (req, res, next) => {
req.userTime = new Date();
next();
});
app.listen(4500, () => console.log('server started'));ROUTER-LEVEL MIDDLEWARE
Router-level middleware działa podobnie jak application-level middleware jedyna różnica jest taka iż ten rodzaj middleware działa w obrembie instancji express.Router().
Przykład
const express = require('express');
const router = express.Router()
router.use((req, res, next) => {
console.log('current time', new Date());
next();
});
// ...ERROR-HANDLING MIDDLEWARE
Error-handling middleware obsługuje błędy oprogramowania. Ten rodzaj middleware przyjmuje cztery argumenty.
Definicja tego rodzaju middleware wygląda podobnie jak w przypadku wcześniejszych typów.
Przykład
const express = require('express');
const app = express();
app.use((error, req, res, next) => {
console.error(error.message);
res.send(500, error.message);
});
// ...BUILT-IN MIDDLEWARE
Built-in middleware czyli wbudowane w webframework Express oprogramowanie pośrednie.
- express.static - middleware odpowiedzialny za udostępnianie statycznych zasobów
- express.json - parsowanie zawartości przychodzącego z żądania typu JSON
- express.urlencoded - parsowanie zawartości przychodzącego z żądania z formularza
BUILT-IN MIDDLEWARE
Od wersji 4.x, Express udostępnia jedynie trzy wcześniej wymienione funkcje pośrednie.
Reszta middleware jest rozwijana w odzielnych modułach.
THIRD-PARTY MIDDLEWARE
Third-party middleware czyli funkcje pośrednie stworzone przez innych poza zespołem twórców framework'a Express.
Przykład
const express = require('express');
const bodyParser = require('body-parser'):
const app = express();
app.use(bodyParser.json());
// ...Template
Template
Express udostępnia mechanizm, który umożliwia korzystanie ze statycznych plików szablonów w aplikacji.
W środowisku wykonawczym silnik szablonów zastępuje zmienne w pliku statycznym, rzeczywistymi wartościami i przekształca szablon w plik HTML wysyłany do użytkownika.
Template engines
Niektóre popularne silniki szablonów współpracują z Express'em(np. JADE/Pug, Mustache, EJS).
Express domyślnie używa JADE/Pug jako silnik szablonów.
Render
Aby przerenderować pliki szablonów niezbędna jest odpowiednia konfiguracja:
- ustawić ścieżkę do katalogu gdzie będą znajdować sie szablony, np: app.set('views', './templates');
- ustawić odpowiedni silinik szablonów, np: app.set('view engine', 'pug') oraz pobrać odpowiednią paczkę z npm
Przykład
// npm install pug
const express = require('express');
const app = express();
app.set('view engine', 'pug')
app.get('/', function (req, res) {
const scope = { title: 'some title', header: 'heloo!' };
res.render('index', scope);
});
// ...PUG template
html
head
title= title
body
h1= headerPrzykład (react)
// npm install express-react-views react react-dom
const express = require('express');
const app = express();
const reactViews = require('express-react-views')
app.set('view engine', 'jsx');
app.engine('jsx', reactViews.createEngine());
app.get('/', function (req, res) {
const scope = { name: 'Jan' };
res.render('hello', scope);
});
app.listen(4500, () => console.log("server started"));views/hello.jsx
const React = require('react');
const HelloMessage = (props) => (<div>Hello {props.name}</div>);
module.exports = HelloMessage;Error handling
Error handling
Obsługa błędów odnosi się do sposobu, w jaki framework Express przechwytuje i przetwarza błędy, które występują synchronicznie jaki i asynchronicznie.
Express sam w sobie zawiera domyślną procedurę obsługi błędów, więc jeżeli nie ma takiej potrzeby to nie trzeba jej pisać samodzielnie.
Catching errors
Ważne jest, aby program Express przechwytywał wszystkie błędy występujące podczas uruchamiania programów do obsługi tras jak i middleware.
Błędy występujące w kodzie synchronicznym wewnątrz procedur obsługi tras i oprogramowania pośredniego nie wymagają dodatkowej pracy. Jeśli kod synchroniczny zgłasza błąd, Express przechwytuje go i przetwarza.
Przykład synchroniczny
const express = require('express');
const app = express();
app.get('/', function (req, res) {
throw new Error('some dumb error');
});
// ...Catching errors
W przypadku błędów zwracanych przez funkcje asynchroniczne wywoływane przez procedury obsługi i oprogramowanie pośrednie, należy przekazać je do funkcji next(), w której to Express je przechwyci i przetworzy.
Przykład asynchroniczny
const express = require('express');
const app = express();
app.get('/', function (req, res) {
setTimeout(() => {
const error = new Error('some dumb error');
next(error);
}, 5000);
});
// ...Default error handler
Express dostarcza wbudowaną obsługę błędów, która dba o wszelkie błędy, które mogą wystąpić w aplikacji.
Ta domyślna funkcja obsługi oprogramowania do obsługi błędów jest dodawana na KOŃCU stosu funkcji oprogramowania pośredniego.
Default error handler
Jeśli przekażemy błąd do funkcji next() i nie obsłużymy go w niestandardowej procedurze obsługi błędów, zostanie ona obsłużona przez wbudowany mechanizm obsługi błędów.
Error handlers
Konstrukcja middleware do obsługi błędów przyjmuje cztery argumenty, nie tak jak w przypadku zwykłych funkcji pośrednich. (err, req, res, next)
Middleware zawiązane z obsługą błędów muszą być użyte po dodaniu innych funkcji pośredniczących jak i obsługi ścieżek.
Przykład
// ...
app.use(bodyParser.json());
app.use(cookieParser);
app.get('/', ...);
/// ...
app.use((error, req, res, next) => {
// ...
});
// ...express-middleware-template-error
By Piotr Tarasiuk
express-middleware-template-error
- 190