Layer0のGraphQL Cachingを試してみる

2022.03.16

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

どうも!オペ部の西村祐二です。

Layer0のGraphQL Cachingを試す機会がありましたのでブログにまとめていきたいと思います。

Layer0って何?という方はHPを確認ください。

今回、サンプルのデモアプリケーションを使ってlayer0のGraphQL Cachingを試していきたいと思います。

GraphQL Cachingのドキュメントはこちらになります。

試してみる

今回、キャッシュするGraphQL API

サンプルではSpaceXのデータが取得できるGraphQL APIが設定されており、このGraphQL APIのデータをキャッシュするコンポーネントと、キャッシュしないコンポーネントが実装され、レスポンスの時間を視覚的に確認できるようなアプリケーションとなっています。

公式より提供されているデモアプリケーションのURLはこちらです。

サンプルのデモアプリケーションのソースをローカルから起動させる

サンプルのデモアプリケーションのレポジトリはこちらになります。

※注意点として2022/3/15現在、Node.js v14のみサポートされているので、ローカル環境をNode.js v14にしておく必要があります。

Node.js v14以外だと下記のようなエラーが発生します。

Layer0 supports only Node.js v14 but your current version is v16.13.1.

まず、ローカルにソースコードをcloneしておき、依存ライブラリをインストールします。

$ npm install

下記コマンドを実行して、ローカルでサンプルアプリケーションを立ち上げます。

$ npm run layer0:dev


> graphql-caching-example@0.1.0 layer0:dev /Users/ynishimura/study/layer0/graphql-caching-example
> layer0 dev

> Starting Layer0 in development mode with caching disabled...
> Bundling Layer0 router... done.
Layer0 info - router compiled successfully.
Layer0 info - router compiled successfully.

Layer0 ready on http://127.0.0.1:3000

表示されたURLにアクセスして、サイトにアクセスできることを確認しましょう。

ここでは、特にキャッシュされないことを確認しましょう。

ローカルで本番同等のテストをする

CLIのLayer0を使いローカルで、アプリの本番ビルドを行い、本番環境同等のテストをローカルから実行することができます。

layer0 build && layer0 run --production


?️  Building your app for deployment on Layer0
[Layer0] Running command: npx next build
info  - Using webpack 5. Reason: Enabled by default https://nextjs.org/docs/messages/webpack5
(node:70591) [DEP_WEBPACK_SINGLE_ENTRY_PLUGIN] DeprecationWarning: SingleEntryPlugin was renamed to EntryPlugin
(Use `node --trace-deprecation ...` to show where the warning was created)
info  - Checking validity of types...
info  - Creating an optimized production build...

warn - You have enabled the JIT engine which is currently in preview.
warn - Preview features are not covered by semver, may introduce breaking changes, and can change at any time.
> Creating service worker...
(node:70591) [DEP_WEBPACK_COMPILATION_ASSETS] DeprecationWarning: Compilation.assets will be frozen in future, all modifications are deprecated.
BREAKING CHANGE: No more changes should happen to Compilation.assets after sealing the Compilation.
	Do changes to assets earlier, e. g. in Compilation.hooks.processAssets.
	Make sure to select an appropriate stage from Compilation.PROCESS_ASSETS_STAGE_*.
> Optimizing serverless functions (Webpack 5)
info  - Compiled successfully
info  - Collecting page data...
info  - Generating static pages (0/3)
info  - Generating static pages (3/3)
info  - Finalizing page optimization...

Page                              Size     First Load JS
┌ ○ /                             14.5 kB         127 kB
├   /_app                         0 B             112 kB
└ ○ /404                          3.17 kB         115 kB
+ First Load JS shared by all     112 kB
  ├ chunks/framework.923004.js    42 kB
  ├ chunks/main.0d42f8.js         20.6 kB
  ├ chunks/pages/_app.2c8ab7.js   48.8 kB
  ├ chunks/webpack.6aa242.js      812 B
  └ css/25fa975f249b7eac511b.css  2.07 kB

λ  (Lambda)  server-side renders at runtime (uses getInitialProps or getServerSideProps)
○  (Static)  automatically rendered as static HTML (uses no initial props)
●  (SSG)     automatically generated as static HTML + JSON (uses getStaticProps)
   (ISR)     incremental static regeneration (uses revalidate in getStaticProps)

> Bundling Layer0 router... done.
Next.js routes (locales: none)

仕組みとしては --production を設定すると、serverless-offline を使用して Layer0のクラウド環境にアップロードされるのと同じようにアプリが実行されるようです。

左側にあるMissionsのレスポンスが右側にあるRocketsのレスポンスに比べて早くなっていることがわかるかと思います。

サンプルのデモアプリケーションをデプロイする

CLIを使うことで簡単にデプロイすることができます。

$ layer0 deploy
? You are not logged in.

✔ To log you in we're going to open your browser and visit Layer0 Developer Console. › Continue
Authenticating user!
? You are now logged in as ynishimura0922@gmail.com

You have uncommitted changes. No commit URL will be stored in app.layer0.co.

・
・
・
***** Deployment Complete *********************************************************
*                                                                                 *
*  ?  Layer0 Developer Console:                                                   *
*  https://app.layer0.co/<your url>                                                *
*                                                                                 *
*  ? Website:                                                                    *
*  https://<your url>                                                             *
*                                                                                 *
***********************************************************************************

Console画面へのURL、払い出されたURLが表示されるのでアクセスしてみましょう。

Console画面はメトリクス、設定、アクティビティなどいろいろ確認できたり、設定できたりで良い感じです。

キャッシュの設定を変更してみる

maxAgeSecondsの設定を変更し、キャッシュの設定を変更してみます。 もともと60 * 60だったものを60に変更してみます。

router.js

const { Router } = require('@layer0/core/router')
const { nextRoutes } = require('@layer0/next')

module.exports = new Router()
  .match('/service-worker.js', ({ serviceWorker }) => {
    return serviceWorker('.next/static/service-worker.js')
  })
  .graphqlOperation('GetMissions', ({ proxy, cache }) => {
    cache({
      edge: {
        maxAgeSeconds: 60,
        staleWhileRevalidateSeconds: 60 * 60 * 24, // this way stale items can still be prefetched
      },
      browser: {
        maxAgeSeconds: 0,
      },
    })
    proxy('graphql') // forward posts requests to apollo unaltered
  })
  .graphqlOperation('GetRockets', ({ proxy, cache }) => {
    cache({
      edge: false,
    })
    proxy('graphql') // forward posts requests to apollo unaltered
  })
  .use(nextRoutes) // automatically adds routes for all files under /pages

再デプロイします。

$ layer0 deploy

サイトにアクセスしヘッダーまわりを確認するとTTLが3600.000から60.000に変わっており、きちんと設定が反映されていることがわかりました。

基本的にrouter.jsかlayer0.config.js、service-worker.js、next.config.jsあたりをイジっていけば良さそうです。

さいごに

簡単ですがLayer0のGraphQL Cachingを試してみました。

提供されているデモアプリケーションがとてもわかりやすく、簡単に挙動など把握することができました。

また、CLIも良くできているので特に詰まることなくデプロイなどができました。

GraphQL APIを使っており、オリジンへの負荷を減らすためにキャッシュしたいと考えている方は、今回紹介したサンプルのデモアプリケーションを触ってみると良いかなと思います。

Layer0は今回紹介した機能以外にも、たくさん機能があるので時間があれば紹介していきたいと思います。

誰かの参考になれば幸いです。