ContentfulのTechnical Limit(API call数制限 429 Too Many Requests)をapollo clientで回避する方法


はじめに

こんにちは。 KDDIアジャイル開発センターの小板橋です。 この記事は、KDDI Engineer&Designer Advent Calendar 2021の20日目の記事です。

今回は、ContentfulというHeadlessCMSを利用した際に起こるTechnical Limit(API call数制限 429Too Many Requests)をApollo clientで回避する方法についてまとめていきたいと思います。

なぜこんな記事を書いたのか

現在、Next.jsとContentfulを利用したポータルサイトの開発を行なっているのですが、その中でContentfulにおけるTechnical Limitの制限により問題が発生した為、今回その原因と解決方法について記事にしてみました。

ContentfulにおけるTechnical Limit

ContentfulにおけるTechnical Limitは、ここに記載があるのですが、今回ボトルネックになったのは、「Content Delivery API (CDA) calls (includes GraphQL calls)」の秒間55requestという制限になります。
これは、秒間に55request以上の負荷がcontentful側にかかった場合に、HTTPステータスが429で返却されてしまうというものです。

  • 現在開発しているポータルサイトでは、contentfulのエンドポイントで提供しているGraphQLを利用しています。
  • また、ポータル自体はNext.jsを利用し全ページSSG構成をとっています。

この時、何が発生するのかというと静的ページの生成時に、下記のようなコードで非同期に画面生成に必要なデータをbuildする際にContentfulのエンドポイントに対しRequestします。
そうすると、各画面に必要なデータをNext.jsは非同期にfetchしにいくので、ページ数が多ければ多いほど、このContentfulにおけるTechnical Limitである、秒間のRequestに達する可能性が高くなるのです。

getStaticProps_sample.js
export async function getStaticProps(context) {
  return {
    props: {}, // will be passed to the page component as props
  }
}

解決策

  • 色々この問題を解決する方法を検討した中で、一番簡単に対処できた方法というのが、GraphQLのクライアント向けライブラリであるApollo clientのoption機能を利用した方法です。

  • Apollo clientには、Retry Linkという機能がoptionで設定することができます。

これが何かというと、ネットワークまたはサーバーのエラーが原因でRequest操作が失敗した場合に、Request操作を複数回リトライすることができるという機能です。
Apollo ClientはデフォルトではRequest操作のリトライを行いません。
なので、ReqponseでHTTPステータスが429のToo Many Requestsが返却された場合には、エラーで落ちてしまいます。

  • @apollo/client/link/retryのRetryLinkを使用することで、Request操作のリトライを行うことができます。
RetryLink_sample.js
import { RetryLink } from "@apollo/client/link/retry";

const link = new RetryLink();

このRetryLinkではさらに細かいリトライ処理の条件を指定することができます。
今回は、delay.initialというoptionとdelay.maxというオプションを利用し、秒間55requestに達しないように調整しました。

まとめ

今回ポータルサイトの開発にSaaSであるHeadless CMSのcontentfulを利用させていただいたのですが、SaaSを利用する際のデメリットとして、このようなTechnical Limitの制約で詰まることがあるのがネックだなと感じました。