viewModelCachingMiddleware

Source
import { viewModelCachingMiddleware } from "@prestojs/rest";
viewModelCachingMiddleware(viewModelMapping,options)

Middleware to transform and cache a response

The response is transformed & cached according to viewModelMapping.

The simplest form of a mapping is to a Model:

const middleware = [viewModelCachingMiddleware(User)];
const getUser = new Endpoint(new UrlPattern('/users/:id/'), { middleware });

If an element is a response is an array then it will transparently be treated as a list of objects of the mapping type and the transformation function will be invoked for each element one by one:

const middleware = [viewModelCachingMiddleware(User)];
// Response is a single User instance:
const userRetrieve = new Endpoint(new UrlPattern('/users/:id/'), { middleware });
// Response is an array of User instances
// (declaration is the same but the response handler will treat it differently)
const userList = new Endpoint(new UrlPattern('/users/'), { middleware });

If the response is an object mapping different models you can specify how each key is transformed. Each response value will be treated as an array/individual object automatically:

const middleware = viewModelCachingMiddleware({
users: User,
bookings: Booking,
});

Dot notation is also supported for nested objects (again each element may be a single object or an array of objects)

const middleware = viewModelCachingMiddleware({
"records.users": User,
"records.bookings": Booking,
});

The mapping can optionally be a function that returns a mapping or returns a promise that resolves to a mapping. This is useful for dealing with dynamic imports or returning a class that isn't yet defined.

const middleware = viewModelCachingMiddleware(() => {
const Booking = (await import('./Booking')).default;
return {
"records.users": User,
"records.bookings": Booking,
}
});

Each record instance created is also automatically added to the cache.

Usually when deleting a model, the endpoint doesn't return anything. So by default if the endpoint method is DELETE you should pass the model that will be deleted on a successful response.

const middleware = [viewModelCachingMiddleware(User)];
// Response is empty:
const userDelete = new Endpoint(new UrlPattern('/users/:id/'), {
middleware,
method: "DELETE"
});

Sometimes a deletion will cause a related model to change and you might want to return the modified model data. In order to do this you specify model to be deleted as the deleteViewModel and the model(s) to be updated as the viewModelMapping. Note that if you provide a viewModelMapping that isn't a single model without providing the deleteViewModel option, you will get an error.

const middleware = [viewModelCachingMiddleware({"records.bookings": Booking}, {deleteViewModel: User})];
// Response would include the updated related bookings, with the number of diners reduced by 1
const updatedBookings = new Endpoint(new UrlPattern('/users/:id/'), {
middleware,
method: "DELETE"
});

NOTE: If using with paginationMiddleware then this must come before paginationMiddleware.

ParameterTypeDescription
*viewModelMappingViewModelMappingDef

The mapping to use for caching as described above. When the request method is DELETE this is assumed to be the model that should be removed from the cache unless you provide options.deleteViewModel. If deleteViewModel is provided then this value is used to cache the response of the delete call.

options.deleteViewModelViewModel Class|
Function

By default the mapping passed to viewModelCacheMiddleware is assumed to be the model to delete. In some cases you may want to return additional data from an endpoint and need to define a more advanced mapping - in these cases you can specify deleteViewModel as the model to delete and the mapping will be used to cache the result.

options.getDeleteId

A function to return the ID to used when a DELETE occurs. This id is used to remove the item with that ID from the cache.

Defaults to returning the url argument id (eg. from a UrlPattern like /users/:id).

Specify this function if you use a different argument name or the ID is passed some other way (eg. in query string)

The function can have an optional validateEndpoint property attached which should be a function that accepts the Endpoint instance. This allows the function to validate the endpoint when it is created to eg. check that the UrlPattern includes the expected argument name.

MiddlewareObject
KeyTypeDescription
init
Function
prepare
Function
process
Function