Skip to content

Latest commit

 

History

History
57 lines (40 loc) · 2.68 KB

File metadata and controls

57 lines (40 loc) · 2.68 KB

Long term cache

Long term caching of endpoints is designed for static sites or server side rendered sites that use a moderate number of data entries, eg. blog posts, products, services, showcases, etc…

It is enabled using config.hash. When true, the endpoints JSON files will be created using a content based hash in their name.

It will also generate a manifest.json file to load on first page load, like a Webpack manifest. It contains a hash tree that maps each endpoint's name to its hash. However its size should be watched a lot more closely as there might be a lot more API entries than JS/CSS/… files to load with Webpack.

When rendering server side, the manifest must be either:

  • required or imported and inlined as a global variable (eg. window.__API__) in the HTML response, and then eventually handled by a state management library (Redux, MobX, Angular, etc…) and cached client side using sessionStorage, localStorage, or AppCache

  • imported in a dedicated service/api.js module, which must be loaded itself by the client app either on page load or on demand, ie. using import or import(), bundled with other JS entries or with async (normal) chunks

Example using Redux:

    const { list, page, slug } = requestArgs
    const { categories, entities, indexes } = reduxStore.getState().apiManifest

    const categories = fetch(categories).then(response => response.json())
    const entities = fetch(indexes[list][page]).then(response => response.json())
    const entity = fetch(entities[slug]).then(response => response.json())

Example using service/api.js (static import):

    import api from './manifest.json' // Generated by markdown-api

    /**
     * get :: Query -> FetchInit -> Promise Error Response
     *
     * Query => { type: EntityType, slug?: EntitySlug, list?: IndexName, page?: Number }
     */
    const get = (query, initFetch) => {
        let path
        if (query.type === 'categories') {
            path = `${api['categories']}`
        } else if (query.list) {
            path = `${api[type].indexes[list][page]}`
        } else if (query.slug) {
            path = `${api[type].entities[slug]}`
        } else if (!path) {
            throw Error('Unable to construct API path to fetch')
        }
        return fetch(path, initFetch).then(response => reponse.json())
    }

Versioning

If config.hash and config.subVersion are both true, stale endpoints will not be removed. This feature might be used to diff between updates, like in a Github repository.

Note: you can also version control only source files, host them on Github, fetch diffs using its API, and render source/processed content client side.