API Maker

The framework for AI era

Performance

Automatic Caching

One setting, and repeat reads come from Redis instead of your database.

Turn on enableCaching for a database, a table or an API. API Maker keeps each response in Redis, answers the same request from there, and removes the cached reads of a table as soon as it is written through API Maker. You write no caching code.

See it live

Step through it, slow it down, or open the full canvas.

api-maker/features/automatic-cachingLive
  • Request
  • From the database
  • From the Redis cache
  • Write / reset
Requests
0sent
Cache hits
0from Redis
DB reads
0PostgreSQL
Keys
0in Redis

Caching is one setting. Set enableCaching: true in the settings of a database or a table, or of a custom or system API. No caching code to write.

How it works

  1. Caching is one setting.

    Set enableCaching: true in the settings of a database or a table, or of a custom or system API. No caching code to write.

  2. The first read fills the cache.

    The key is the table plus a hash of the request and its API user. On a miss, API Maker reads the database and keeps the response in Redis.

  3. Repeat reads skip the database.

    The same request is answered straight from Redis, with the header x-am-data-source: cache. The database is not touched.

  4. A write resets the cache of its table.

    Insert, update or delete through API Maker, and every cached read of products is removed. The next read gets the new price.

  5. Every API user has its own entry.

    The API user is part of the key, so users with different field access never share a response. Keys expire after 7200 s.

  6. Reset it yourself when you need to.

    Send x-am-cache-control: reset_cache to force a fresh read, or call g.sys.cache.resetCacheDB from your code.

What you get

Writes reset the cache

Save, update or delete rows through API Maker and every cached read of that table is removed. An update or delete also clears cached tables whose schema points to it.

One entry per API user

The API user is part of the cache key, so users with different field access never get each other's response.

Dependencies you declare

A cached custom API can list the tables and APIs it depends on in resetCacheOnModificationOf. When one of them changes, its cache is cleared.

See where it came from

Every response carries x-am-data-source: cache or api, so you always know if the database was read.

Reset it when you want

Send x-am-cache-control: reset_cache to force a fresh read, or call g.sys.cache.resetCacheDB, resetCacheCustomApis or resetCacheSystemApis from your code.

Separate per tenant

With multi-tenant instances the tenant is part of the key, so one customer never receives the cache of another.

An example

A product catalog

Thousands of visitors open the same category pages, while prices change a few times a day. With caching on the products table, the pages are served from Redis, and the moment someone updates a price through the API the cached pages of that table are dropped. The next visitor sees the new price.

Table settings : cache every read API of this tablecollection-settings.ts
import * as T from 'types';let instanceColSetting: T.IInstanceApiSettingsTypes = {    enableCaching: true,};module.exports = instanceColSetting;
Custom API settings : cache it, and clear it when products changecustom-api-settings.ts
import * as T from 'types';let customApi: T.ICustomApiSettingsTypes = {    name: 'Top Products',    requestMethod: T.ERequestMethod.GET,    path: '/top-products',    enableCaching: true,    resetCacheOnModificationOf: [        'DB:shop:main:products', // a write to this table clears the cache of this API    ],    errorList: [],};module.exports = customApi;
Reset a table cache from your codecustom-api.ts
await g.sys.cache.resetCacheDB({    instance: 'shop',    database: 'main',    collection: 'products',});

Good to know

  • Caching needs the external Redis of API Maker (redisExternal), set in package.json or in the settings of the root user.
  • Only writes made through API Maker reset the cache. A change made directly in the database is seen after the key expires (7200 s by default, redisValueExpireInSeconds) or after you reset the cache.
  • Responses longer than 1,000,000 characters are not cached (maxCharsResToCache), so large exports do not fill Redis.
  • For database APIs, caching is a database or table setting, not a setting of a single generated API.

Questions

Which requests are cached?

The read APIs of a table with caching on: get all, get by id, query, aggregate, count and distinct. Custom and system APIs are cached when their own settings have enableCaching: true.

What is the cache key made of?

The table (or API), the tenant if any, and a hash of the API user, the request body, query and parameters, and the headers that change the answer: content type, secret, response format, key case, flattening and encryption.

How do I know a response came from the cache?

Look at the x-am-data-source response header: cache means Redis answered, api means the API ran.

Can I keep keys longer or shorter?

Yes. redisValueExpireInSeconds in the redisExternal settings sets how long keys live. The default is 7200 seconds.