Plugins
feTS Client provides a powerful plugin system that allows you to hook into the request/response lifecycle and customize the behavior of the client.
feTS Client Plugin
A plugin in feTS is a function that returns an object with the following optional properties:
onRequestInit
- Called before the request is sent by the client.- It includes an
endResponse
method that accepts aResponse
object to short-circuit the request.
- It includes an
onFetch
- Called when the underlyingfetch
function is invoked by the client.- It allows you to modify the
fetch
options or replace thefetch
function itself.
- It allows you to modify the
onResponse
- Called after the request is handled by the router.- It enables you to modify the response or throw an error to prevent the response from being returned.
Handling Cookies With Built-in Cookies Plugin
To handle cookies separately from the environment, you can use the useCookieStore
plugin.
Note: This plugin is not needed for browsers.
import { CookieStore, useClientCookieStore } from 'fets'
// Create a cookie store with a cookie string
const cookieStore = new CookieStore('')
const client = createClient<typeof someoas>({
plugins: [useClientCookieStore(cookieStore)]
})
You can store cookies in a custom storage by utilizing the events provided by feTS’ CookieStore
object, which implements the WHATWG CookieStore. Learn more in the
official documentation
Retrying on Fail With ‘Fetch-Retry’ as a Plugin
You can install fetch-retry
from npm and use it to create a plugin:
import fetchRetry from 'fetch-retry'
export function useRetry(): ClientPlugin {
return {
onFetch({ fetchFn, setFetchFn }) {
setFetchFn(fetchRetry(fetchFn))
}
}
}
const client = createClient<typeof someoas>({
plugins: [useRetry()]
})
HTTP Caching on Non-Browser Environments With ‘fetchache’
Server environments typically lack the built-in HTTP caching logic found in browsers. To bring this
behavior to server-side environments, you can use fetchache
.
fetchache
requires a key-value cache implementation, which can be Redis or a simple in-memory
cache. The following example demonstrates using an in-memory approach:
import { fetchFactory, KeyValueCache } from 'fetchache'
import { ClientPlugin } from 'fets'
const mapForCache = new Map<string, any>()
const cache: KeyValueCache = {
async get(key) {
return _map.get(key)
},
async set(key, value) {
_map.set(key, value)
},
async delete(key) {
_map.delete(key)
}
}
const useCache: ClientPlugin = {
onFetch({ fetchFn, setFetchFn }) {
setFetchFn(
fetchFactory({
fetch: fetchFn,
cache,
Response
})
)
}
}
const client = createClient<typeof someoas>({
plugins: [useCache()]
})
Adding Auth Headers to Requests
import { ClientPlugin } from 'fets'
export function useAuth(token: string): ClientPlugin {
return {
onRequestInit({ requestInit }) {
requestInit.headers = {
...requestInit.headers,
Authorization: `Bearer ${token}`
}
}
}
}
const client = createClient<typeof someoas>({
plugins: [useAuth()]
})
Calculating a request’s duration
import { ClientPlugin } from 'fets'
export function useDuration(): ClientPlugin {
const startTimeByRequestInit = new WeakMap<RequestInit, number>()
return {
onRequestInit({ requestInit }) {
startTimeByRequestInit.set(requestInit, Date.now())
},
onResponse({ response }) {
const start = startTimeByRequestInit.get(response.requestInit)
if (start) {
const duration = Date.now() - Number(start)
console.log(`Request took ${duration}ms`)
}
}
}
}