How ShiftLeft provides a snappy UI experience by caching API requests in the browser
ShiftLeft Engineering uses an API-first implementation approach. We have a single, unified JSON REST API used by our UI, CLI, integrations, custom scripts, and more. With so many dependencies, API performance and responsiveness is a clear priority for us.
Our UI is one API consumer that we pay extra attention to. It makes way more API requests than our CLI or other integrations. Clicking around the ShiftLeft dashboard and navigating through findings for different applications requires several API calls to load the required data, and those API calls may require expensive/long database queries.
Users may not notice their CI pipelines take a couple of seconds longer than usual, but every 100 ms counts when users are looking at spinners on their screen waiting for results of a scan to load. For many expensive requests, we let the browser cache the API response.
ShiftLeft is a developer-friendly SAST platform that scans your code for security issues on every pull request. But if you’re not submitting new scans, your results don’t change, and we take advantage of that for caching. Here’s an example with the Applications dashboard:
In the screenshot above, the initial page load calls the findings summary API endpoint which takes 1.47 seconds and returns 65 KB of data. Subsequent requests take less than 0.1 seconds because there were no changes to the results.
How it works: Last-Modified, If-Modified-Since, ETag, If-None-Match
For a few expensive endpoints the API returns a Last-Modified header with a timestamp, and that lets your browser cache the API response. On the next request to that endpoint, your browser includes a If-Modified-Since header with the same timestamp. We also send a hash of your applications list and scan IDs as part of the ETag header, which your browser sends back in the If-None-Match header.
If there are *no new scans, and no changes to the apps list *since that time, we stop early and return HTTP 304 Not Modified. This lets the browser use the cached response it already has, and our API avoids running expensive database queries.
Using just those 4 headers, we’re able to leverage browser-side caching and provide a fast UI experience for our users. The benefit of using browser-side caching is it is fast to implement, requires no additional infrastructure or storage on our backend, and no changes in our UI code.