172 lines
4.0 KiB
Plaintext
172 lines
4.0 KiB
Plaintext
---
|
||
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'
|
||
|
||
# Example: Access Logged-In User
|
||
|
||
This document gives an example of how you can use middlewares to register the logged-in user in the dependency container of your commerce application. You can then access the logged-in user in other resources, such as services.
|
||
|
||
:::tip
|
||
|
||
You can apply the same steps if you want to register the current customer.
|
||
|
||
:::
|
||
|
||
Learn more about [middlewares in its guide](./add-middleware.mdx).
|
||
|
||
## Step 1: Create the Middleware
|
||
|
||
Create the file `src/api/middlewares.ts` with the following content:
|
||
|
||
```ts title="src/api/middlewares.ts"
|
||
import type {
|
||
MiddlewaresConfig,
|
||
User,
|
||
UserService,
|
||
} from "@medusajs/medusa"
|
||
import type {
|
||
MedusaNextFunction,
|
||
MedusaRequest,
|
||
MedusaResponse,
|
||
} from "@medusajs/medusa"
|
||
|
||
const registerLoggedInUser = async (
|
||
req: MedusaRequest,
|
||
res: MedusaResponse,
|
||
next: MedusaNextFunction
|
||
) => {
|
||
let loggedInUser: User | null = null
|
||
|
||
if (req.user && req.user.userId) {
|
||
const userService =
|
||
req.scope.resolve("userService") as UserService
|
||
loggedInUser = await userService.retrieve(req.user.userId)
|
||
}
|
||
|
||
req.scope.register({
|
||
loggedInUser: {
|
||
resolve: () => loggedInUser,
|
||
},
|
||
})
|
||
|
||
next()
|
||
}
|
||
|
||
export const config: MiddlewaresConfig = {
|
||
routes: [
|
||
{
|
||
matcher: "/admin/products",
|
||
middlewares: [registerLoggedInUser],
|
||
},
|
||
],
|
||
}
|
||
```
|
||
|
||
This creates a `registerLoggedInUser` middleware that handles registering the logged-in user in the dependency container.
|
||
|
||
It then applies this middleware on the `/admin/products` API Route. You can change that to be the route of any other API Route or a pattern that matches multiple routes.
|
||
|
||
---
|
||
|
||
## Step 2: Use in a Service
|
||
|
||
Access the logged-in user resource in the constructor of a service:
|
||
|
||
<!-- eslint-disable prefer-rest-params -->
|
||
|
||
```ts
|
||
import { Lifetime } from "awilix"
|
||
import {
|
||
TransactionBaseService,
|
||
User,
|
||
} from "@medusajs/medusa"
|
||
|
||
class HelloService extends TransactionBaseService {
|
||
|
||
protected readonly loggedInUser_: User | null
|
||
|
||
constructor(container, options) {
|
||
super(...arguments)
|
||
|
||
try {
|
||
this.loggedInUser_ = container.loggedInUser
|
||
} catch (e) {
|
||
// avoid errors when backend first runs
|
||
}
|
||
}
|
||
|
||
// ...
|
||
}
|
||
|
||
export default HelloService
|
||
```
|
||
|
||
If you're accessing it in an extended core service, it’s important to change the lifetime of the service to `Lifetime.SCOPED`. For example:
|
||
|
||
<!-- eslint-disable prefer-rest-params -->
|
||
|
||
```ts
|
||
import { Lifetime } from "awilix"
|
||
import {
|
||
ProductService as MedusaProductService,
|
||
User,
|
||
} from "@medusajs/medusa"
|
||
|
||
// extend core product service
|
||
class ProductService extends MedusaProductService {
|
||
// The default life time for a core service is SINGLETON
|
||
static LIFE_TIME = Lifetime.SCOPED
|
||
|
||
protected readonly loggedInUser_: User | null
|
||
|
||
constructor(container, options) {
|
||
super(...arguments)
|
||
|
||
this.loggedInUser_ = container.loggedInUser
|
||
}
|
||
}
|
||
|
||
export default ProductService
|
||
```
|
||
|
||
You can learn more about the importance of changing the service lifetime in the [Middlewares documentation](./add-middleware.mdx#note-about-services-lifetime).
|
||
|
||
---
|
||
|
||
## Step 3: Test it Out
|
||
|
||
To test out your implementation, run the following command in the root directory of the Medusa backend to transpile your changes:
|
||
|
||
```bash npm2yarn
|
||
npm run build
|
||
```
|
||
|
||
Then, run your backend with the following command:
|
||
|
||
```bash npm2yarn
|
||
npx medusa develop
|
||
```
|
||
|
||
If you try accessing the API Routes you added the middleware to, you should see your implementation working as expected.
|
||
|
||
---
|
||
|
||
## Troubleshooting
|
||
|
||
<DetailsList
|
||
sections={[
|
||
{
|
||
title: 'AwilixResolutionError: Could Not Resolve X',
|
||
content: <ServiceLifetimeSection />
|
||
},
|
||
{
|
||
title: 'AwilixResolutionError: Could Not Resolve X (Custom Registration)',
|
||
content: <CustomRegistrationSection />
|
||
}
|
||
]}
|
||
/>
|