---
addHowToData: true
---
import DetailsList from '@site/src/components/DetailsList'
import ServiceLifetimeSection from '../../troubleshooting/awilix-resolution-error/_service-lifetime.md'
import CustomRegistrationSection from '../../troubleshooting/awilix-resolution-error/_custom-registration.md'
# Middlewares
In this document, you’ll learn how to add a middleware to existing or custom API Routes in Medusa.
:::tip
v1.17.2 of `@medusajs/medusa` introduced a new approach to creating middlewares using a single `middlewares.ts` file. You can still use the [Express Router Approach](./add-middleware-express-route.mdx), however, it's highly recommended that you start using this new approach.
:::
## Basic Implementation
```ts title=src/api/middlewares.ts
import type { MiddlewaresConfig } from "@medusajs/medusa"
import type {
MedusaNextFunction,
MedusaRequest,
MedusaResponse,
} from "@medusajs/medusa"
const storeMiddleware = (
req: MedusaRequest,
res: MedusaResponse,
next: MedusaNextFunction
) => {
// do something
next()
}
export const config: MiddlewaresConfig = {
routes: [
{
matcher: "/store/*",
middlewares: [storeMiddleware],
},
],
}
```
A middleware is a function that has access to the `MedusaRequest` and `MedusaResponse` objects that are passed to API Route method handlers.
Middlewares are used to perform an action when a request is sent to an API Route, or modify the response of an API route, among other usages.
### middlewares.ts File
Middlewares are defined in the `src/api/middlewares.ts` file. This file must expose a config object of type `MiddlewaresConfig` imported from `@medusajs/medusa`.
This object accepts a parameter `routes`, whose value is an array of middleware route objects. Each middleware route object accepts the following properties:
- The `matcher` property accepts a string or a regular expression that will be used to check whether the middlewares should be applied on a API Routes.
- The `middlewares` property is an array of middlewares that should be applied on API Routes matching the pattern specified in `matcher`.
---
## Build Files
Similar to custom API Routes, you must transpile the files under `src` into the `dist` directory for the backend to load them.
To do that, run the following command before running the Medusa backend:
```bash npm2yarn
npm run build
```
You can then test that the middleware is working by running the backend.
---
## Register New Resources in Dependency Container
In some cases, you may need to register a resource to use within your commerce application. For example, you may want to register the logged-in user to access it in other resources, such as services. You can do that in your middleware.
:::tip
If you want to register a logged-in user and access it in your resources, you can check out [this example guide](./example-logged-in-user.mdx).
:::
To register a new resource in the dependency container, use the `MedusaRequest` object's `scope.register` method. It accepts an object, where each key is the name to be registered in the dependency container, and its value is an object that has a `resolve` property.
The `resolve`'s value is a function that returns the resource to be registered in the dependency container.
For example:
```ts title=src/api/middlewares.ts
import type { MiddlewaresConfig } from "@medusajs/medusa"
import type {
MedusaNextFunction,
MedusaRequest,
MedusaResponse,
} from "@medusajs/medusa"
const customResource = (
req: MedusaRequest,
res: MedusaResponse,
next: MedusaNextFunction) => {
req.scope.register({
customResource: {
resolve: () => "my custom resource",
},
})
next()
}
export const config: MiddlewaresConfig = {
routes: [
{
matcher: "/store/*",
middlewares: [customResource],
},
],
}
```
You can then load this new resource within other resources. For example, to load it in a service:
```ts title=src/services/custom-service.ts
import { TransactionBaseService } from "@medusajs/medusa"
class CustomService extends TransactionBaseService {
constructor(container, options) {
super(...arguments)
// use the registered resource.
try {
container.customResource
} catch (e) {
// avoid errors when the backend first loads
}
}
}
export default CustomService
```
:::note
Make sure to wrap your usage of the new resource in a try-catch block when you use it in a constructor. This is to avoid errors that can arise when the backend first loads, as the resource isn't registered yet.
:::
### Note About Services Lifetime
If you want to access new registrations in the dependency container within a service, you must set the lifetime of the service either to `Lifetime.SCOPED` or `Lifetime.TRANSIENT`. Services that have a `Lifetime.SINGLETON` lifetime can't access new registrations since they're resolved and cached in the root dependency container beforehand. You can learn more in the [Create Services documentation](../services/create-service.mdx#service-life-time).
For custom services, no additional action is required as the default lifetime is `Lifetime.SCOPED`. However, if you extend a core service, you must change the lifetime since the default lifetime for core services is `Lifetime.SINGLETON`.
For example:
```ts
import { Lifetime } from "awilix"
import {
ProductService as MedusaProductService,
} from "@medusajs/medusa"
// extending ProductService from the core
class ProductService extends MedusaProductService {
// The default life time for a core service is SINGLETON
static LIFE_TIME = Lifetime.SCOPED
constructor(container, options) {
super(...arguments)
// use the registered resource.
try {
container.customResource
} catch (e) {
// avoid errors when the backend first loads
}
}
// ...
}
export default ProductService
```
---
## Troubleshooting
},
{
title: 'AwilixResolutionError: Could Not Resolve X (Custom Registration)',
content:
}
]}
/>
---
## See Also
- [Store API reference](https://docs.medusajs.com/api/store)
- [Admin API reference](https://docs.medusajs.com/api/admin)