2021-04-11

Next.jsのAPIを使ってみた

Next.jsのAPIをBFFとして使ってみた。簡単な使い方と注意点を書いてみる。

post image

はじめに

Next.jsの 9.0 から登場した API Routing を使って、簡単なAPIを作ってみた。 そのAPIをBFFとして使ってみたので使い方を紹介する。

API Routingとは

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にしているが、中身は自分のクライアントに合わせて自由に書けば良い。

パラメーター付きのAPI

例えば、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としては微妙
  • ホスティング先によっては使えない

本当のAPIとしては微妙

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 RoutingSSR として実現されるので、ホスティング先がSSRを対応してなければ使えなくなる。 実際にnetlifyの場合はサポートしてなく、 API Routing を使えない。

自分ももともとnetlifyを使っていて、この機能を試すためにvercelに移行した。 基本的なホスティングしかしないのでそこまで使い方は違いないが、やはりNEXT.jsの開発元なのでAPI Routingもサポートしてくれていた。