Extending the Middleware
When developing your storefront, there will be times when you need to customize the way the middleware and integrations run. For example, you might want to add or edit a new API endpoint or even modify the Express.js application itself. Vue Storefront's Server Middleware allows you to do this using extensions.
Adding an extension
Extensions can be added to any integration in your middleware.config.ts
file by creating an extensions
function. This function accepts an array of extensions and returns a new array with your extension added.
You can use this function to add your own extensions or to modify existing ones.
export const integrations = {
magento: {
// ...
extensions: (extensions) => [
...extensions, // don't forget to add existing extensions
{
name: 'extension-name',
extendApiMethods: { /* ... */ },
extendApp: (app) => { /* ... */ },
hooks: () => { /* ... */ }
}
]
}
}
}
Creating an extension
You can define as many extensions as you want. Each extension has the following structure:
const extension = {
name: 'extension-name',
extendApiMethods: {
customMethod: (context, params) => { /* ... */ },
},
extendApp: (app) => { /* ... */ },
hooks: (req, res) => {
return {
beforeCreate: ({ configuration }) => configuration,
afterCreate: ({ configuration }) => configuration,
beforeCall: ({ configuration, callName, args }) => args,
afterCall: ({ configuration, callName, args, response }) => response
}
}
}
name
- a unique name for your extension,extendApiMethods
- overrides an integration's API Client to modify default behavior or add new API endpointsextendApp
- gives you access to the Express.js apphooks
- defines lifecycle hooks of API-clientbeforeCreate
- called before API-client creates a connection. It accepts an integration configuration as an argument and must return it as well. You can use it to modify the configuration or merge it with the default values,afterCreate
- similar to the previous function, but called after the connection has been created. It accepts an integration configuration as an argument and must return it as well. This hook is usually used for cleanup work after altering the configuration inbeforeCreate
,beforeCall
- called before each API-client function. Gives you access to the integration configuration, function name, and arguments. Can be used to modify the arguments based on the input parameters and must return them,afterCall
- called after each API-client function. Gives you access to the configuration, function name, arguments and response. Can be used to modify the response based on the input parameters and must return it.
Lifecycle Hooks
Middleware extensions allow you to extend your Express.js server, register additional API endpoints, or hook into the lifecycle of a request sent to a given Server Middleware integration from the application.
Use Cases
Adding an Endpoint
To register a new API endpoint, you can register a custom extension and use the extendApiMethods
property. API
endpoints cannot be registered directly. Let's look at an example:
export const integrations = {
magento: {
// ...
extensions: (extensions) => [
...extensions,
{
name: 'extension-name',
extendApiMethods: {
getProductsBySKU: async (context, params) => {
const response = await context.client.post('/getProductsBySKU', params);
return response.data;
}
}
}
],
}
}
All integrations can be extended, however, this example extends the Magento 2 integration, to give more context about real-life usage. We registered getProductBySku
in extendApiMethods
which creates a new /api/magento/getProductBySku
endpoint.
This method accepts two parameters:
context
- integration context which includes:config
- integration configurationclient
- API client created inpackages/api-client/src/index.server.ts
req
- HTTP request objectres
- HTTP response objectextensions
- extensions registered within integrationcustomQueries
- custom GraphQL queries registered within integration (used only with GraphQL)extendQuery
- helper function for handling custom queries (used only with GraphQL)
params
- parameters passed in the request's body
To try it, you can run a simple curl
command:
curl '{SERVER_DOMAIN}/api/magento/getProductBySku`' \
-X POST \
-H 'content-type: application/json' \
-d '[{ "id": 1, "name": "John" }]'