liaisev5.3.1
/Built-in middleware options

Reference

Built-in middleware options

This page lists the options of the middleware in liaise/middleware, and of the clients’ log option. Look here when you tune retries, the cache or logging. Retries, caching and logging shows when to use each one.

RetryOptions

retryMiddleware(options) takes a RetryOptions. retryMiddleware(n) is short for retryMiddleware({ max: n }), and retryMiddleware() means { max: 3 }.

OptionTypeDefaultWhat it does
maxnumber3Retries after the first attempt. max: 2 means up to 3 calls in all.
delay'exponential' | 'linear' | (attempt: number) => number'exponential'The wait before each retry. Exponential is baseDelay * 2^(attempt-1) and linear is baseDelay * attempt. A function gets the 1-based attempt and returns milliseconds. If it throws or returns NaN or an infinite number, the exponential wait is used, and a negative wait counts as 0.
baseDelaynumber (ms)250The first wait, before jitter and Retry-After.
maxDelaynumber (ms)30000The longest any wait can be, a Retry-After value included. Infinity means no cap.
jitterbooleantrueWaits a random time between 0 and the computed delay, so many clients don’t retry at the same moment. Never applied to a Retry-After value.
respectRetryAfterbooleantrueUses the server’s Retry-After header, in seconds or as a date, in place of the computed wait. maxDelay still caps it. A value it can’t read is ignored.
retryOn(result: Result<unknown>, attempt: number) => booleanr => (r.error?.status ?? 0) >= 500Whether to retry. It gets the 1-based number of the attempt it would start, and is called even once max is reached. If it throws, the call isn’t retried.
onRetry(info: RetryInfo) => void—Called before each wait. Its return value is ignored, and if it throws, the call goes on.

The default retryOn retries only a 5xx. A 4xx, a 429 and a network error come back as they are, unless your retryOn says otherwise (Retry failed calls). A cancel or a deadline during a wait ends the call with kind: 'abort' or 'timeout'.

RetryInfo, the argument to onRetry:

FieldWhat it holds
attemptThe retry about to run, counting from 1.
maxThe configured max.
delayThe wait about to start, in milliseconds, after jitter and Retry-After.
resultThe Result that caused this retry.

Cache options

cacheMiddleware(options) returns a middleware with a clear() method, typed CacheMiddleware. Each call makes its own store.

OptionTypeDefaultWhat it does
ttlnumber (ms)300000 (5 minutes)How long an entry is served. An expired entry is removed when it is next read.
maxSizenumber50How many entries the store keeps. When it is full, the oldest entry is dropped.
debugbooleanfalseLogs [liaise cache] HIT or MISS, with the endpoint and its params, to the console.
methodsreadonly string[]['GET', 'HEAD']The methods it caches, compared without regard to case. A call with any other method goes straight to the network and is never stored. GraphQL sends every operation as a POST, so a cache on a query operation needs ['POST'] (Caching queries).

Only successes are stored. clear() empties the store, and passing the middleware in skipMiddleware skips it for one call (Cache repeated reads). What goes into the key is under Cache key.

Log options

The log option of both clients takes a boolean or a LogOptions, and logMiddleware(options) takes a LogOptions. log: true and a bare logMiddleware mean { enabled: true, data: false }. With log left out or false, nothing is logged.

OptionTypeDefaultWhat it does
enabledbooleantrueTurns logging on or off. With false, log does nothing and costs nothing, and logMiddleware passes every call straight through.
databooleanfalseAlso prints each call’s data, or its error.body on failure. An object or array goes to console.table, anything else to console.log, which is also used where console.table is missing.

Each call logs one line when it starts and one when it ends:

[liaise] → <method> <endpoint> <url>
[liaise] ← <endpoint> OK (<ms>ms)
[liaise] ← <endpoint> ERROR <status> (<ms>ms)
[liaise] ← <endpoint> OK (<ms>ms, shared)

The time covers everything that runs inside the logger. For log that is the whole call, and for logMiddleware it is the middleware after it and the request. An error with no response logs status 0. Either end line ends in , shared when the call joined a shared request. A console that throws never fails the call.

Next: poll() and pollUntil() options lists the options of the polling helpers, and what pollUntil resolves with.

esc