️ Эта библиотека была написана для поддержки маршрутов API, которые используют маршрутизатор следующего.js Pages. Он не был протестирован с помощью маршрутизатора приложения.
Next.js API Маршруты - смехотворно веселый и простой способ добавить функциональность бэкэнд в приложение React. Однако, когда приходит время добавить промежуточное программное обеспечение, нет простого способа реализовать его.
Официальные документы Next.js рекомендуют написать функции внутри вашего обработчика маршрута API. Это огромный шаг назад по сравнению с чистыми API, предоставленными Express.js или Koa.js.
Эта библиотека пытается обеспечить минимальные, чистые, композиционные промежуточные схемы, которые являются как продуктивными, так и приятными в использовании.
labeluse import { label , Middleware } from "next-api-middleware" ;
import * as Sentry from "@sentry/nextjs" ;
import nanoid from "nanoid" ;
// 1 – Create middleware functions
const captureErrors : Middleware = async ( req , res , next ) => {
try {
// Catch any errors that are thrown in remaining
// middleware and the API route handler
await next ( ) ;
} catch ( err ) {
const eventId = Sentry . captureException ( err ) ;
res . status ( 500 ) ;
res . json ( { error : err } ) ;
}
} ;
const addRequestId : Middleware = async ( req , res , next ) => {
// Let remaining middleware and API route execute
await next ( ) ;
// Apply header
res . setHeader ( "X-Response-ID" , nanoid ( ) ) ;
} ;
// 2 – Use `label` to assemble all middleware
const withMiddleware = label (
{
addRequestId ,
sentry : captureErrors , // <-- Optionally alias middleware
} ,
[ "sentry" ] // <-- Provide a list of middleware to call automatically
) ;
// 3 – Define your API route handler
const apiRouteHandler = async ( req , res ) => {
res . status ( 200 ) ;
res . send ( "Hello world!" ) ;
} ;
// 4 – Choose middleware to invoke for this API route
export default withMiddleware ( "addRequestId" ) ( apiRouteHandler ) ; Моя ментальная модель того, как эта библиотека обрабатывает функции промежуточного программного обеспечения, - это «обмотка и разматывающий стек».
Давайте представим, что вы использовали label , чтобы добавить две функции промежуточного программного обеспечения в маршрут API.
Когда вступает запрос, это грубое впечатление о том, как этот запрос пробивается через все функции промежуточного программного обеспечения, самого обработка маршрута API, а затем резервное копирование промежуточного программного обеспечения.
|-----------------|-----------------|--------------------|
| Middleware #1 | Middleware #2 | API Route Handler |
|-----------------|-----------------|--------------------|
| | | |
Request ------|----> Setup -----|----> Setup -----|-->------| |
| | | | |
|-----------------|-----------------| V |
| | | |
| await next() | await next() | API stuff |
| | | |
|-----------------|-----------------| | |
| | | | |
Response <----|--- Teardown <---|--- Teardown <---|---------| |
| | | |
|-----------------|-----------------|--------------------|
В то время как это грязная диаграмма ASCII, я думаю, что это дает правильное впечатление. Запрос вводит свой путь, хотя каждое промежуточное программное обеспечение функционирует подряд, попадает в обработчик маршрута API, а затем продолжает «расслабиться» через стек.
Каждая функция промежуточного программного обеспечения имеет возможность пройти три этапа:
Фаза «настройки» охватывает все, что происходит, прежде чем await next() . Фаза «ожидания» на самом деле просто await next() . Фаза «разрыв» - это оставшийся код в функции промежуточного программного обеспечения после await next() .
Стоит отметить, что, хотя эти этапы доступны для всех функций промежуточного программного обеспечения, вам не нужно использовать их всех.
Например, при ошибке, выявив промежуточное программное обеспечение, вы можете просто await next() в блоке try / catch . С другой стороны, у вас может быть запрос промежуточного программного обеспечения, которое отражает время начала на этапе установки, ожидает, а затем захватывает время завершения на этапе разрыва.
labelЭто основная утилита для создания повторных коллекций промежуточного программного обеспечения для использования на протяжении многих маршрутов API Next.js.
const withMiddleware = label ( middleware , defaults ) ; middleware : объект, содержащий функции промежуточного программного обеспечения или массивы промежуточного программного обеспеченияdefaults : (необязательно) массив клавиш middleware , которые будут вызовом автоматически label возвращает функцию (условно называемой withMiddleware ), которая использует карри, чтобы принять список имен промежуточного программного обеспечения, за которым следует функция обработчика API NEST.JS.
Как withMiddleware , в файлах маршрута API будет импортироваться и используется в операторе экспорта по умолчанию:
import { withMiddleware } from "../helpers/my-middleware" ;
const apiRouteHandler = async ( req , res ) => {
...
}
export default withMiddleware ( "foo" , "bar" , "baz" ) ( apiRouteHandler ) ; Хотя label может содержать много функций промежуточного программного обеспечения, фактическое промежуточное программное обеспечение, вызванное маршрутом API, определяется именами, передаваемыми для withMiddleware .
const logErrors = async ( req , res , next ) => {
try {
await next ( ) ;
} catch ( error ) {
console . error ( error ) ;
res . status ( 500 ) ;
res . json ( { error } ) ;
}
} ;
const withMiddleware = label ( {
logErrors ,
} ) ;
// export default withMiddleware("logErrors")(apiRouteHandler); const withMiddleware = label ( {
error : logErrors ,
} ) ;
// export default withMiddleware("error")(apiRouteHandler); import { foo , bar , baz } from "./my-middleware" ;
const withMiddleware = label ( {
error : logErrors ,
myGroup : [ foo , bar , baz ] ,
} ) ;
// export default withMiddleware("error", "myGroup")(apiRouteHandler); const withMiddleware = label (
{
error : logErrors ,
myGroup : [ foo , bar , baz ] ,
} ,
[ "error" ]
) ;
// export default withMiddleware("myGroup")(apiRouteHandler);use Эта утилита принимает функции промежуточного программного обеспечения напрямую и выполняет их все по порядку. Это более простая альтернатива label , которая может быть полезна для обработки одноразовых функций промежуточного программного обеспечения.
const withInlineMiddleware = use ( ... middleware ) ; middleware : список функций промежуточного программного обеспечения и/или массивов функций промежуточного программного обеспечения use возвращение функции, которая принимает обработчик api api steck.js.
import { use } from "next-api-middleware" ;
import cors from "cors" ;
const apiRouteThatOnlyNeedsCORS = async ( req , res ) => {
...
}
export default use ( cors ( ) ) ( apiRouteThatOnlyNeedsCORS ) ; См. Примеры.md для более подробных примеров label и use .
Поскольку use и label принимают значения, которые оценивают функции промежуточного программного обеспечения, это дает возможность создать пользовательские фабрики промежуточного программного обеспечения.
Вот пример фабрики, которая генерирует функцию промежуточного программного обеспечения, чтобы разрешить запросы только с помощью данного метода HTTP:
import { Middleware } from "next-api-middleware" ;
const httpMethod = (
allowedHttpMethod : "GET" | "POST" | "PATCH"
) : Middleware => {
return async function ( req , res , next ) {
if ( req . method === allowedHttpMethod || req . method == "OPTIONS" ) {
await next ( ) ;
} else {
res . status ( 404 ) ;
res . end ( ) ;
}
} ;
} ;
export const postRequestsOnlyMiddleware = httpMethod ( "POST" ) ; Middleware вдохновлено асинкновым стилем промежуточного программного обеспечения, популяризированным Koa.js.
type Middleware < Request = NextApiRequest , Response = NextApiResponse > = (
req : Request ,
res : Response ,
next : ( ) => Promise < void >
) => Promise < void > ;