How to cache new fetch requests in sw-precache - sw-precache

I am trying to use sw-precache to enhance the off-line experience in a web app.
As I understand it, the library (and correct me if I am wrong) is to pre-cache all static assets. What about new requests?
Say I want to cache the response of a new get fetch request.
Is there away to override/extend the already provided
self.addEventListener('fetch', ... in the generated sw file
I may be very much missing something here. enlgihten me please...

You need to use the option runtimeCaching. This option enables caching for those new fetch requests.
You pass it an array of objects specifying what urlPattern you want to match, the handler you wish to use for the matched request, and some other options you can check in the link.

Related

RESTDataSource - How to know if response comes from get request or cache

I need to get some data from a REST API in my GraphQL API. For that I'm extending RESTDataSource from apollo-datasource-rest.
From what I understood, RESTDataSource caches automatically requests but I'd like to verify if it is indeed cached. Is there a way to know if my request is getting its data from the cache or if it's hitting the REST API?
I noticed that the first request takes some time, but the following ones are way faster and also, the didReceiveResponse method is not called everytime I make a query. Is it because the data is loaded from the cache?
I'm using apollo-server-express.
Thanks for your help!
You can time the requests like following:
console.time('restdatasource get req')
this.get(url)
console.timeEnd('restdatasource get req')
Now, if the time is under 100-150 milliseconds, that should be a request coming from the cache.
You can monitor the console, under the network tab. You will be able to see what endpoints the application is calling. If it uses cached data, there will be no new request to your endpoint logged
If you are trying to verify this locally, one good option is to setup a local proxy so that you can see all the network calls being made. (no network call meaning the call was read from cache) Then you can simply configure your app using this apollo documentation to forward all outgoing calls through a proxy like mitmproxy.

Request URI too long on spartacus services

I've been trying to make use of service.getNavigation() method, but apparently the Request URI is too long which causes this error:
Request-URI Too Long
The requested URL's length exceeds the capacity limit for this server.
Is there a spartacus config that can resolve this issue?
Or is this supposed to be handled in the cloud (ccv2) config?
Not sure which service are you talking about specifically and what data are you passing there. For starters, please read this: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/414
Additionally it would benefit everyone if you could say something about the service you're using and the data you are trying to pass/get.
The navigation component is firing a request for all componentIds. If you have a navigation with a lot of (root?) elements, the maximum length of HTTP GET request might be too long for the given client or server.
The initial implementation of loading components was actually done by a POST request, but the impression was that we would not need to support requests with so many components. I guess we were wrong.
Luckily, the legacy POST based request is still in the code base, it's OccCmsComponentAdapter.findComponentsByIdsLegacy.
The easiest way for you to use this code, is to provide a CustomOccCmsComponentAdapter, that extends from OccCmsComponentAdapter. Then you can override the findComponentsByIds method and simply call the super.findComponentsByIdsLegacy and pass in a copy of the arguments.
A more cleaner way would be to override the CmsComponentConnector and directly delegate the load to the adapter.findComponentsByIdsLegacy. I would not start here, as it's more complicated. Do a POC with the first suggested approach.

Quickly-editable config file, not visible to public visitors?

I am in the middle of working with, and getting a handle on Vuejs. I would like to code my app in a way that it has some configurable behaviors, so that I could play with parameter values, like you do when you edit your Sublime preferences, but without having to compile my app again. Ideally, I would want a situation where I could have my colleagues be able to fiddle with settings all day long, by editing a file over FTP maybe, or over some interface....
The only way I know how to do it now, is to place those settings in a separate file, but as the app runs in the client, that file would have to be fetched via another HTTP request, meaning it's a publicly readable file. Even though there isn't any sensitive information in such a configuration file, I still feel a little wonky about having it public like that, if it can be avoided in any way...
Can it be avoided?
I dont think you can avoid this. One way or another your config file will be loaded into the vuejs application, therefore being visible to the end user (with some effort).
Even putting the file outside of the public folder wouldnt help you much, because then it is unavailable for HTTP to request the file. It would only be available to your compile process in this case.
So a possible solution could be to have some sort of HTTP request that requests GET example.com/settings and returns you a JSON object. Then you could have your app make a cookie like config_key = H47DXHJK12 (or better a UUID https://en.wikipedia.org/wiki/Universally_unique_identifier) which would be the access key for a specific config object.
Your application must then request GET example.com/settings (which should send the config_key cookie), and your config object for this secret key will be returned. If the user clears his cookies, a new request will return an empty config.

How to force dispatcher cache urls with get parameters

As I understood after reading these links:
How to find out what does dispatcher cache?
http://docs.adobe.com/docs/en/dispatcher.html
The Dispatcher always requests the document directly from the AEM instance in the following cases:
If the HTTP method is not GET. Other common methods are POST for form data and HEAD for the HTTP header.
If the request URI contains a question mark "?". This usually indicates a dynamic page, such as a search result, which does not need to be cached.
The file extension is missing. The web server needs the extension to determine the document type (the MIME-type).
The authentication header is set (this can be configured)
But I want to cache url with parameters.
If I once request myUrl/?p1=1&p2=2&p3=3
then next request to myUrl/?p1=1&p2=2&p3=3 must be served from dispatcher cache, but myUrl/?p1=1&p2=2&p3=3&newParam=newValue should served by CQ for the first time and from dispatcher cache for subsequent requests.
I think the config /ignoreUrlParams is what you are looking for. It can be used to white list the query parameters which are used to determine whether a page is cached / delivered from cache or not.
Check http://docs.adobe.com/docs/en/dispatcher/disp-config.html#Ignoring%20URL%20Parameters for details.
It's not possible to cache the requests that contain query string. Such calls are considered dynamic therefore it should not be expected to cache them.
On the other hand, if you are certain that such request should be cached cause your application/feature is query driven you can work on it this way.
Add Apache rewrite rule that will move the query string of given parameter to selector
(optional) Add a CQ filter that will recognize the selector and move it back to query string
The selector can be constructed in a way: key_value but that puts some constraints on what could be passed here.
You can do this with Apache rewrites BUT it would not be ideal practice. You'll be breaking the pattern that AEM uses.
Instead, use selectors and extensions. E.g. instead of server.com/mypage.html?somevalue=true, use:
server.com/mypage.myvalue-true.html
Most things you will need to do that would ever get cached will work this way just fine. If you give me more details about your requirements and what you are trying to achieve, I can help you perfect the solution.

Does Dojo framework support grouping/bunching of same type of commands to avoid multiple request to server?

I know, we can do grouping of same kind of Ajax requests to server.
But just wanted to know if Dojo supports this or let us know if this feature doesn't depend upon Dojo framework or jquery...
Depending on the type of request you do, and how response headers are set, some kinds of AJAX requests can be cached by the browser itself, just like it would cache a normal webpage.
Outside of the browser caching stuff, I don't know of any framework that does caching at the request level like that. So, if you need a request to not be repeated the only way to be sure is to not issue the request in the first place.
In Dojo's case, for example, it is quite common to issue AJAX requests via something like dojo/store/JsonRest instead of doing them by hand. In this case it is quite easy to use something like a dojo/store/Cache to add a cacheing layer in front of the JsonRest store.
http://livedocs.dojotoolkit.org/dojo/store/Cache
http://www.sitepen.com/blog/2011/02/15/dojo-object-stores/