2021-04-11
Next.jsのAPIをBFFとして使ってみた。簡単な使い方と注意点を書いてみる。
Next.jsの 9.0 から登場した API Routing を使って、簡単なAPIを作ってみた。 そのAPIをBFFとして使ってみたので使い方を紹介する。
API Routing とはNext.jsで簡単にAPIを作れる機能のこと。 既存のNext.jsのルーティングのように、APIのルーティングもディレクトリの構造で書ける。
pages
|-- api
| |-- posts
| | |-- [slug].tsx
| | |-- index.tsx
|-- posts.tsx
|-- index.tsx
|-- _app.tsx
|-- _document.tsx
上記のように pagesの下にapiというディレクトリをおくだけて良い 。 とても簡単に書ける。
この例だと /api/posts
と /api/posts/[slug]
という2つのAPIが作れる。
/api/posts
はContentfulから全てのポストをとってくるAPIだとして書いてみると
import type { NextApiRequest, NextApiResponse } from "next";
export default async (req: NextApiRequest, res: NextApiResponse) => {
const entries = await client.getEntries({
content_type: "post",
});
res.statusCode = 200;
res.setHeader("Content-type", "application/json");
res.end(JSON.stringify(entries.items.map((item) => convertPost(item))));
};
const convertPost = (item) => {
return {
title: item.fields.title,
subtitle: item.fields.subtitle,
body: item.fields.body,
slug: item.fields.slug,
publishedAt: item.fields.publishedAt,
};
};
基本的にNodeのAPIサーバーのように書くことができる。 返す値は基本的にJSONにしているが、中身は自分のクライアントに合わせて自由に書けば良い。
例えば、Contentfulから指定した条件に一致したポストだけを返すAPIを作るとしよう。
/api/posts/[slug]
というAPIを作るとした場合、このAPIはパスで指定した [slug] でポストを探すAPIになる。
import type { NextApiRequest, NextApiResponse } from "next";
export default async (req: NextApiRequest, res: NextApiResponse) => {
const entries = await client.getEntries({
content_type: post,
"fields.slug": req.query.slug,
});
res.statusCode = 200;
res.setHeader("Content-type", "application/json");
res.end(JSON.stringify(convertPost(entries.items[0])));
};
const convertPost = (item) => {
return {
title: item.fields.title,
subtitle: item.fields.subtitle,
body: item.fields.body,
slug: item.fields.slug,
publishedAt: item.fields.publishedAt,
};
};
req.query.slug でパスで指定した [slug] を取得することができる。 この先の流れは同じく、必要な形に合わせて返してあげるだけで良い。
このブログでもこの API Routing を使ってSSGで作ってるが、いくつか注意する点がある。
API Routingとはしてるが、個人的に WEB APIとして使うのは非推奨 。
Next.jsはあくまでReactを用いること前提のフレームワークであり、APIルーティングはおまけ程度のものです。リクエストメソッドのフィルタリング、リクエストボディのバリデーションなどもすべて自前で記述しなければならないため、本格的なWeb APIサーバを開発するには向きません。
Qiitaブログ | web-apiフレームワークではないので機能的に貧弱
例えば、DBから値を取得したり、認証の処理を行ったり、といったビジネスロジックが多く含まれるようなAPIが必要な場合は、 API Routing は向いてない。 Reactベースではあるので書こうとすれば書けるかも知れないが、あまりおすすめはできない。
個人的にNEXT.jsのAPIは BFFとして使う ことが最適だと思っている。 BFFってなに?
クライアントサイドで必要なAPIをラップして、使いやすい形にして返してあげる、それ以上のことはしない、ということが自分の使い方。まさにBFFとして使っている。 上に書いたサンプルコードもContentfulのSDKは使っているが、基本的には ContentfulのAPIを叩いて、形を変えて返す だけの APIコンポジション を実現したBFFになる。
API Routing は SSR として実現されるので、ホスティング先がSSRを対応してなければ使えなくなる。 実際にnetlifyの場合はサポートしてなく、 API Routing を使えない。
自分ももともとnetlifyを使っていて、この機能を試すためにvercelに移行した。 基本的なホスティングしかしないのでそこまで使い方は違いないが、やはりNEXT.jsの開発元なのでAPI Routingもサポートしてくれていた。