ショ和 このライブラリは、Next.jsページルーターを使用するAPIルートをサポートするために書かれています。アプリルーターではテストされていません。
Next.js APIルートは、Reactアプリにバックエンド機能を追加するための途方もなく楽しく簡単な方法です。ただし、ミドルウェアを追加する時が来たとき、それを実装する簡単な方法はありません。
公式のNext.jsドキュメントは、APIルートハンドラー内に機能を作成することを推奨しています。これは、Express.jsまたはKOA.JSが提供するクリーンAPIと比較して、大きな一歩です。
このライブラリは、生産的で快適な使用が快適な最小限のクリーンなミドルウェアパターンを提供しようとします。
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を使用して2つのミドルウェア関数をAPIルートに追加したと想像してみましょう。
リクエストが入ってくると、これはすべてのミドルウェア関数、APIルートハンドラー自体を介してそのリクエストがどのように進行し、ミドルウェアを介してバックアップするかという大まかな印象です。
|-----------------|-----------------|--------------------|
| Middleware #1 | Middleware #2 | API Route Handler |
|-----------------|-----------------|--------------------|
| | | |
Request ------|----> Setup -----|----> Setup -----|-->------| |
| | | | |
|-----------------|-----------------| V |
| | | |
| await next() | await next() | API stuff |
| | | |
|-----------------|-----------------| | |
| | | | |
Response <----|--- Teardown <---|--- Teardown <---|---------| |
| | | |
|-----------------|-----------------|--------------------|
これは不器用なASCII図ですが、正しい印象を与えると思います。リクエストは、各ミドルウェアが連続して機能し、APIルートハンドラーにヒットし、スタックを「巻き戻す」ために進みます。
すべてのミドルウェア機能には、3つのフェーズを経る機会があります。
「セットアップ」フェーズはawait next()前に起こるすべてのものをカバーします。 「待機」フェーズは本当にawait next() 。 「分解」フェーズはawait next()後、ミドルウェア関数内の残りのコードです。
これらのフェーズはすべてのミドルウェア関数で利用可能であるが、それらすべてを利用する必要はないことは注目に値します。
たとえば、ミドルウェアのエラーをキャッチすると、 try / catchブロックでawait next() 。一方、セットアップフェーズ中の開始時間をキャプチャし、待機してから、分解フェーズで終了時間をキャプチャするタイミングミドルウェアを要求する場合があります。
labelこれは、多くのNext.JS APIルートで使用するためのミドルウェアの再利用可能なコレクションを作成するための主要なユーティリティです。
const withMiddleware = label ( middleware , defaults ) ; middleware :ミドルウェア関数またはミドルウェアの配列を含むオブジェクトdefaults :(オプション)自動的に呼び出されるmiddlewareキーの配列label 、カリーを使用して呼び出されるミドルウェア名のリストを受け入れる関数( withMiddlewareと呼ばれる)を返し、その後にnext.js APIハンドラー関数が続きます。
通常、 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このユーティリティは、ミドルウェア機能を直接受け入れ、それらをすべて順番に実行します。これは、1回限りのミドルウェア関数を処理するのに役立つlabelに代わるよりシンプルな代替品です。
const withInlineMiddleware = use ( ... middleware ) ; middleware :ミドルウェア関数および/またはミドルウェア関数の配列のリストuse next.js APIルートハンドラーを受け入れる関数を返します。
import { use } from "next-api-middleware" ;
import cors from "cors" ;
const apiRouteThatOnlyNeedsCORS = async ( req , res ) => {
...
}
export default use ( cors ( ) ) ( apiRouteThatOnlyNeedsCORS ) ; 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 > ;