ServiceWorker as a Service, または Universal ServiceWorker という発想
ServiceWorker とは本質的に リクエスト&レスポンスモデルであるので、それをサーバーサイドで実装で一種のサーバーロジックとして動かしてしまって良いはずだ ー
という発想に目から鱗だったので、ちょっと考えてみたいと思う。
ここで試せる。
Cloudflare はCDN業者なので、 それに特化して Service Worker as a Service みたいな表現はしていないが、実態としてはサーバーサイド ServiceWorker だ。Fastly では varnish のミドルウェアなどでキャッシュ破棄設定のロジックやリダイレクトを書いていたが、それが ServiceWorker という体を取っている(ように見える)。
ちゃんと使い込んでいないので、おそらくだが、 cache オブジェクトの実装が cloudflare の asset cache の実装にそのままつながっていて、そこでキャッシュ破棄、構築命令に翻訳されているのだろう。
追記: 実際はレスポンスを書き換えるだけで、まだキャッシュ実装はないが、やりたいとのこと
I know this is an old tweet, but to answer your question: install/activate don't seem relevant to CF workers due to their server-side model. We do plan to implement the Cache API eventually but most use cases only really need fetch() to be cached.
— Kenton Varda (@KentonVarda) 2018年2月19日
Cloudflare の手法で優れているのは、現状、すべてのブラウザが Service Worker を実装しているわけではない(というかIEのことだが)ので、将来的には標準的な手法になるはずの中間層を用意したことで、たとえばpush イベントも(Safariであっても) をサーバーサイドで溜め込んで置いたり出来る。また、クライアント用 Service Worker と密に連携したスクリプトも配信できる。ビジネス的にもストレージサイズやイベントドリブンなエンドポイントの実行回数で課金できる。
イベントドリブン標準としての ServiceWorker
ミドルウェアでなんでもできる、という点で AWS Lambda や Google Cloud Function と同じようなものとして使うことが可能だろう。FaaS の1スペックとして、ServiceWorker as a Service という形式はアリだろうか。
cloudflare の チュートリアルで配布されてるコードはこんな感じ。
addEventListener('fetch', event => { event.respondWith(fetchAndLog(event.request)) }) /** * Fetch and log a given request object * @param {Request} request */ async function fetchAndLog(request) { console.log('Got request', request) const response = await fetch(request) console.log('Got response', response) return response }
普通の service worker のコードだ。普通の。
毎度 Lambda と Cloud Function を使ってて思うのは、いまいち Node 側からのインターフェースが仕様化・共通化されていないので、毎回ベンダロックインされたコードを書くことになってしまっている。それぐらいだったら一応は仕様がW3Cではっきりしている ServiceWorker の仕様を使うのは筋悪ではない、と思う。
しかしどうせ各プラットフォームが独自な名前空間を持ってイベントを生やしてくる。Cloudflare もその方向を最初検討したようだし、それ自体は現実的なユースケースを踏まえると必要だと思う。実際ユニバーサルな ServiceWorker というものは、なんらかの抽象化層を経ないと到達し得ないだろう。
また、express で cluster モジュールなどを使ってOSSなサーバーサイドServiceWorkerを実装するのは、そこまで難しくなさそうに見える。Open FaaSなどとも方向性が同じになる。
なので、方向性としては歓迎したいが、大きなプレーヤーが標準化に向けて動いてくれないと難しそう。
たとえばちょっと前に ServiceWorker 上で express 動かすのが一部で試されてたけど、逆で、ServiceWorker のコードを読み込む express みたいな発想のが伸びしろがありそう
— human eslint --fix (@mizchi) 2018年3月15日