PWA: Workbox Routing 和訳 (その２)

# Workbox Routing

参照元ページ: https://developers.google.com/web/tools/workbox/modules/workbox-routing

## Navigation Routeの書き方

あなたのサイトがSPA(シングルページアプリケーション)なら、`navigation requests`に対するすべてのレスポンスには`NavigationRoute`が使えます。

補足: `navigation requests`の詳しい説明は[こちら](https://developers.google.com/web/fundamentals/primers/service-workers/high-performance-loading?hl=ja)。ざっくり言うと「ナビゲーションリクエストとは、『document』を宛先とするリクエストである」とのことです。

```
workbox.routing.registerNavigationRoute(
  // 事前に'/single-page-app.html'がプリキャッシュされているとします
  // 一致するキャッシューキーを取得します
  workbox.precaching.getCacheKeyForURL('single-page-app.html')
)
```
*[参考](https://developers.google.com/web/tools/workbox/reference-docs/latest/module-workbox-precaching.PrecacheController): `getCacheKeyForURL`はurlを引数にとりキャッシュキー(`string`型)を返します。もしurlが`/index.html`の様にバージョニングされていなければ、キャッシュキーは（searchパラメータ付きの）url自身になります。

ユーザーがブラウザからあなたのサイトにアクセスするたび、ページへのリクエストは`navigation request`扱いになり、キャッシュされた`/single-page-app.html`がレスポンスとしてサーブされます。(注: `workbox-caching`もしくはご自身のインストールステップ経由でページを事前にキャッシュしている場合)

デフォルトではすべての`navigation requests`に適用されます。もしURLのサブセットのみに適用を制限知る場合は、`whitelist`と`blacklist`でルーティングとマッチしたページをターゲットとすることが可能です。

```
workbox.routing.registerNavigationRoute(
  // 事前に'/single-pafe-app.html'がプリキャッシュされているとします
  // 一致するキャッシューキーを取得します
  workbox.precaching.getCacheKeyForURL('single-page-app.html', {
  whitelist: [
    new RegExp('/blog/')
  ],
  blacklist: [
    new RegExp('/blog/restricted/'),
  ]
  })
)
```

`whitelist`と`blacklist`に同じURLが指定されている場合は`blacklist`の指定が生かされます。

## Default Handlerの設定

ルートとマッチしていないリクエストに対して「ハンドラー」を設定したい場合、`default handler`を使うことができます。

```
workbox.routing.setDefaultHandler(({url, event, params}) => {
  ...
});
```

## Catch Handlerの設定

リクエストを捌いている時、ルートの設定がエラーとなってしまう場合は、`catch handler`でレスポンスを設定
できます。

```
workbox.routing.setCatchHandler(({event}) => {
  if (event.request.mode === 'navigate') {
    return caches.match('/error-page.html');
  }
  return Response.error();
})
```

## GET以外のリクエストへのルートの設定

デフォルトでは全てのルートは`GET`リクエストを想定しています。

`POST`など他のリクエストのルートを設定したい場合、リクエストを登録する際にメソッドを定義する必要があります。

```
workbox.routing.registerRoute(
  matchCb,
  handlerCb,
  'POST'
)

workbox.routing.regiterRoute(
  new RegExp('/api/.*\.json'),
  handlerCb,
  'POST'
)
```

## ルーターのログ

`workbox-routing`はWorkboxで処理されるURLをハイライト表示してログを返してくれます。

![](https://developers.google.com/web/tools/workbox/images/modules/workbox-routing/workbox-routing-standard-logs.png)

ログを詳細に表示させるにはログレベルを`debug`に設定します。詳細は[こちら](https://developers.google.com/web/tools/workbox/guides/troubleshoot-and-debug)

補足:

```
workbox.core.setLogLevel(workbox.core.LOG_LEVELS.debug);

```

![](https://developers.google.com/web/tools/workbox/images/modules/workbox-routing/workbox-routing-logs.png)

##　応用編

`handleRequest()`メソッドを使用すればルーティングの細かな設定が可能です。

```
const router = new DefaultRouter();
self.addEventListener('fetch', (evebt => {}
  const responsePromise = router.handleRequest(event);
  if (responsePromise) {
  // 指定したリクエストを捌くルートが見つかったとき
   event.respondWith(responsePromise)
  } else {
    リクエストを捌くルートが見つからないとき
  }
))
```

`Router`を直接使ってルートを設定する場合、`Route`クラスもしくはextendされたクラスを使う必要があります。

```
const router = new DefaultRouter();
router.registerRoute(new Route(matchCb, handlerCb));
router.registerRoute(new RegExpRoute(new RegExp(...), handlerCb));
router.registerRoute(new NavigationRoute(handlerCb));
```