️ تمت كتابة هذه المكتبة لدعم طرق API التي تستخدم جهاز التوجيه Next.js Pages. لم يتم اختباره مع جهاز توجيه التطبيق.
تعتبر طرق API jex.js طريقة ممتعة للغاية وبسيطة لإضافة وظائف الواجهة الخلفية إلى تطبيق React. ومع ذلك ، عندما يحين الوقت لإضافة البرامج الوسيطة ، لا توجد طريقة سهلة لتنفيذها.
توصي مستندات Next.js الرسمية بكتابة وظائف داخل معالج مسار 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 crummy ، أعتقد أنه يعطي الانطباع الصحيح. يطرف الطلب طريقه على الرغم من أن كل برامج الوسيطة تعمل على التوالي ، وضرب معالج مسار API ، ثم يتابع "الاسترخاء" في طريقه عبر المكدس.
كل وظيفة الوسيطة لديها فرصة للذهاب إلى ثلاث مراحل:
تغطي مرحلة "الإعداد" كل ما يحدث قبل await next() . مرحلة "الانتظار" هي في الحقيقة في await next() . مرحلة "teardown" هي الكود المتبقي داخل دالة الوسيطة بعد await next() .
تجدر الإشارة إلى أنه على الرغم من أن هذه المراحل متاحة لجميع وظائف الوسيطة ، إلا أنك لا تحتاج إلى الاستفادة منها جميعًا.
على سبيل المثال ، في خطأ في التقاط البرامج الوسيطة ، يمكنك ببساطة أن await next() في كتلة try / catch . من ناحية أخرى ، قد تكون لديك طلب توقيت الوسيطة التي تلتقط وقت البدء خلال مرحلة الإعداد ، والانتظار ، ثم يلتقط وقت الانتهاء في مرحلة teardown.
labelهذه هي الأداة الأساسية لإنشاء مجموعات إعادة استخدام من الوسيطة للاستخدام خلال العديد من طرق API Next.js.
const withMiddleware = label ( middleware , defaults ) ; middleware : كائن يحتوي على وظائف الوسيطة أو صفائف من الوسيطةdefaults : (اختياري) مجموعة من مفاتيح middleware التي سيتم الاحتجاج بها تلقائيًا تقوم label بإرجاع وظيفة (يشار إليها بشكل تقليدي باسم withMiddleware ) التي تستخدم الكاري لقبول قائمة أسماء الوسيطة المراد التذرع بها ، تليها وظيفة معالج API Next.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 NEXT.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 > ;