nivedita
nivedita

Reputation: 121

how to cache response of a POST request using workbox

is it possible to cache the response of POST request using workbox? my application uses POST request instead of GET to fetch list data , since user credentials are sent along with the request.

Upvotes: 6

Views: 6425

Answers (2)

S. Esteves
S. Esteves

Reputation: 453

You can cache POST request with the following syntax:

workbox.routing.registerRoute(
    <url>,
    <workbox strategy>,
   'POST'
);

Official Documentation: https://developer.chrome.com/docs/workbox/modules/workbox-routing/#defining-a-route-for-non-get-requests

Upvotes: 7

Artem S.
Artem S.

Reputation: 669

Let me clarify S. Esteves' answer.

Browser cache storage doesn't has an ability to persist POST requests as a keys (see spec here).

If innerRequest’s url's scheme is not one of "http" and "https", or innerRequest’s method is not GET, return a promise rejected with a TypeError.

Workbox lets you intercept POST requests (as service worker does on fetch event with GET requests) by passing 'POST' as third parameter to registerRoute function, then you can put some custom logic into handler (but even manually you still unable to save response into cache storage, as it is not supported).

So direct use of Workbox strategies which do cache responses will end up with error (see example here).

So options here are:

  1. (preferable) If you are in touch with backend maintainers ask them to change desired endpoint from POST to GET if it is possible and if POST request is effectively idempotent (so it makes sense to cache it). Modern browsers support get size from 100Kb to 200Kb, so in many cases this option is possible. If POST is not idempotent option is not to cache it.

Quote from here:

HTTP caching is applicable only to idempotent requests, which makes a lot of sense; only idempotent and nullipotent requests yield the same result when run multiple times. In the HTTP world, this fact means that GET requests can be cached but POST requests cannot

However, there can be cases where an idempotent request cannot be sent using GET simply because that request exceeds the limits imposed by popular Internet software.

  1. Alternatively you can try this (credits to jeffposnick) using Workbox:
    1. Get POST request in workbox route handler
    2. Convert it manually to GET request (which is allowed as cache storage keys)
    3. Use this GET request as a key to save cached response in cache storage
    4. Check in the same handler if a request is already saved and respond with cached response
    5. Also I think it is possible to save responses in IndexedDB using requests digests as keys.
workbox.routing.registerRoute(
  /api/, // Change to match your endpoint URL.
  async ({event, url}) => {
    // See https://developers.google.com/web/tools/workbox/guides/route-requests#handling_a_route_with_a_custom_callback
    // Do something here. What it is up to you.
    // Eventually, return a Response object, or else your request will fail.
    return response;
  },
  'POST' // Opt-in to matching POST requests. Only GET is matched by default.
);

Upvotes: 15

Related Questions