Medusa Marketplace #2.1 | Extending StoreService

Search for a command to run...

No comments yet. Be the first to comment.
In this series, I'm going to cover a whole host of points covered in the Medusa.js documentation or not to have a functional marketplace using Medusa.js and Stripe Connect.
Hello everyone! Now that our vendors have access to their store, I can tell they are getting bored. Indeed, without any things to sell, our back office is useless, therefore we're spending this time expanding the product concept and adding a decent b...
Say hello to our new home

Hello everyone! In this new part, we'll be setting up Stripe and Stripe Connect to collect payments from our customers and trigger payments for our vendors. âš Before starting this part, make sure you have a valid Stripe account and have set up Strip...

Hello everyone! In this new section, we'll take a look at payments in preparation for what's to come. What's the goal here? In the same spirit as Orders, we're going to divide a single Payment into several for each store, or to be more transparent, w...

Hello everyone! Many of you have been waiting for this part, so here we're going to cover how to manage orders for each seller. Indeed, the most logical and widely used way is the one outlined by Shahed Nasserin her tutorial series that inspired pers...

Hello everyone! Now that we've extended the ShippingOption and ShippingProfile entities, we can start integrating new features into our services. What's the goal here ? The aim of this part is to override various functions of the ShippingOption and S...

Hello everyone!
In this part of our Medusa.js marketplace journey, we'll continue building on the groundwork we established in the previous sections. This time, our focus will be on extending the StoreService and ProductService to ensure a seamless user experience.
The core objective here is to guarantee that when a user logs into the admin ui, they can seamlessly access their own store based on their store_id. This level of personalization is crucial for providing a tailored experience within our marketplace. As you've noted, the approach involves extending the existing services to achieve this functionality. Let's dive into the details.
We'll create a new file in the services folder, named store.ts, where we'll extend the StoreService to override the retrieve function.
// src/services/store.ts
import { type FindConfig, StoreService as MedusaStoreService, buildQuery } from "@medusajs/medusa"
import { Lifetime } from 'awilix'
import type { User } from "../models/user"
import type { Store } from "../models/store"
class StoreService extends MedusaStoreService {
static LIFE_TIME = Lifetime.TRANSIENT
protected readonly loggedInUser_: User | null
constructor(container, options) {
// @ts-ignore
super(...arguments)
try {
this.loggedInUser_ = container.loggedInUser
} catch (e) {
// avoid errors when backend first runs
}
}
async retrieve(config?: FindConfig<Store>): Promise<Store> {
if (!this.loggedInUser_ || !this.loggedInUser_.store_id) {
// In case there is no loggedInUser or no store_id,
// we just use the original function
// that retrieves the default store
return await super.retrieve(config)
}
const storeRepo = this.activeManager_.withRepository(this.storeRepository_)
const query = buildQuery<Partial<Store>, Store>(
{
id: this.loggedInUser_.store_id,
},
{
...config,
relations: [...(config?.relations || []), 'members'],
},
)
return await storeRepo.findOne(query)
}
}
export default StoreService
In this extended StoreService, we override the retrieve method to check if the logged-in user is defined and have a store_id associated with their account. If so, we use that store_id to retrieve that specific store information. Otherwise, we fall back to the default behavior of the StoreService (which will just use the default store created by the Medusa core loaders)

Well done, now that the right store is displayed, we will extend the products in the next part!
You can access the complete part's code here.
You can contact me on Discord and X with the same username : @adevinwild