API のルーティングは動的ルーティングをサポートし、pages
に使用されるものと同じファイル命名規則に従います。
例えば、API ルート pages/api/post/[pid].js
に以下のコードがあるとします:
export default handler(req, res) {
const { pid } = req.query
res.end(`Post: ${pid}`);
};
このとき、/api/post/abc
へのリクエストは Post: abc
というテキストを返します。
ごく一般的な RESTful パターンは、次のようなルートを設定します:
GET api/posts
- 投稿の一覧を取得します。おそらくページネーションがあります。GET api/posts/12345
- 投稿 ID 12345 を取得します。これは 2 つの方法でモデル化できます:
オプション 1:
/api/posts.js
/api/posts/[postId].js
オプション 2:
/api/posts/index.js
/api/posts/[postId].js
どちらも同等です。3 つ目のオプションとして /api/posts/[postId].js
のみを使うことは正しくありません。なぜなら、どんな状況でも動的ルーティング(すべてのルートのキャッチを含む-下記を参照)には 未定義
な状態はなく、GET api/posts
は /api/posts/[postId].js
に一致しないためです。
角括弧 []
内に 3 つのドット(...
)を追加することで、API ルートを拡張してすべてのパスをキャッチできます。例えば:
pages/api/post/[...slug].js
は /api/post/a
に一致しますが、/api/post/a/b
、/api/post/a/b/c
などにも一致します。備考:
slug
以外の名前も使用できます。例えば:[...param]
一致したパラメータはクエリパラメータ(例では slug
)としてページに送信され、常に配列になり、パス /api/post/a
は次の query
オブジェクトを持ちます:
{ "slug": ["a"] }
そして、/api/post/a/b
やその他の一致するパスである場合、次のように新しいパラメータが配列に追加されます:
{ "slug": ["a", "b"] }
pages/api/post/[...slug].js
の API ルートは、次のようになります:
export default function handler(req, res) {
const {
query: { slug }
} = req;
res.end(`Post: ${slug.join(', ')}`);
};
このとき、/api/post/a/b/c
へのリクエストは Post: a, b, c
というテキストを返します。
すべてのルートをキャッチすることは、[[...slug]]
のようにパラメータを二重角括弧内に含めることでオプショナルにできます。
例えば、pages/api/post/[[...slug]].js
は /api/post
、/api/post/a
、/api/post/a/b
などに一致します。
[...slug]
との主な違いは、パラメータを持たないルートもマッチすることです(上の例では /api/post
)。
query
オブジェクトは次のようになります:
{ } // GET `/api/post` (空のオブジェクト)
{ "slug": ["a"] } // `GET /api/post/a` (要素が1つの配列)
{ "slug": ["a", "b"] } // `GET /api/post/a/b` (要素が複数の配列)
pages/api/post/create.js
- /api/post/create
に一致しますpages/api/post/[pid].js
- /api/post/1
、/api/post/abc
などに一致します。しかし、/api/post/create
には一致しません。pages/api/post/[...slug].js
- /api/post/1/2
、/api/post/a/b/c
などに一致します。しかし、/api/post/create
、/api/post/abc
などには一致しません。さらに詳細については、以下のセクションをお勧めします: