Files
medusa-store/www/apps/docs/content/development/api-routes/example-logged-in-user.mdx
Shahed Nasser 547b16ead5 docs: fix code block titles (#5733)
* docs: fix code block titles

* remove console

* fix build error
2023-11-27 16:08:10 +00:00

172 lines
4.0 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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, its 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 />
}
]}
/>