megazear7 / orison

A server and static site generator built on top of lit-html
http://orison.alexlockhart.me
18 stars 2 forks source link

Create Data Cache #22

Closed megazear7 closed 5 years ago

megazear7 commented 5 years ago

When integrating with APIs multiple pages and partials might need access to the same API data. At large scale this could be problematic, if for example the layout needs the same API data for every page render and you are generating thousands of pages, that is thousands of requests for the same data.

To solve this problem we need an Orison cache which can serve as an unopinionated API wrapper. The developer would create cache loaders that are simply responsible for fetching data from some API.

/src/loaders/example.js

import someAPI from 'some-api';

export default async someId => {

  return someAPI.get(someID);
}

The parameters will come from the calling code. i.e. a page, partial, or layout. It should return some API data based on the params.

/src/pages/index.js
import { html } from 'orison';

export default async context => {
  const dataFromAPI = await context.cache.example(context.data.someId);

  return html`
    <p>${dataFromAPI}</p>
  `;
};

The Orison cache will be available from the context object. The method name will be a camel case version of the file name. It will always return a promise. Sometimes the API will actually be hit. Other times the Orison cache will simply returned the cached data if it is already available.

The orison cache will add methods to the orison.cache object based upon the files under /src/loaders. The method name will be a camel case version of the file name and the method itself will be the default export of the file. This method will be wrapped by a method that ensures the returned result is a promise. The Orison cache will store the returned result in a map unique to the loader where the key is the parameters and the value is the returned result. If future calls to this cache loader already have an entry for the given parameters then it will simply return the result.

Cache loaders can also be added programatically. This can be done by passing a method into the loaders parameter of the OrisonGenerator or OrisonServer:

import OrisonGenerator from 'orison';

const myLoader = async someId => someAPI.get(someID);

new OrisonGenerator({
  rootPath: process.cwd(),
  loaders: {
    'myLoader': myLoader
  }
}).build();