From e1e7d8e5e4dff6b36ae27f7d4370bdc6217dcb2e Mon Sep 17 00:00:00 2001 From: Shahed Nasser Date: Fri, 21 Jul 2023 12:42:21 +0300 Subject: [PATCH] docs: fix options details passed to endpoints (#4579) * docs: fix options details passed to endpoints * added access configuration sections * added section about parsing request body --- docs/content/development/endpoints/create.md | 115 +++++++++++++++++- .../development/events/create-subscriber.md | 33 +++++ .../development/services/create-service.mdx | 36 ++++++ 3 files changed, 181 insertions(+), 3 deletions(-) diff --git a/docs/content/development/endpoints/create.md b/docs/content/development/endpoints/create.md index c7553939a3..fe792ac6eb 100644 --- a/docs/content/development/endpoints/create.md +++ b/docs/content/development/endpoints/create.md @@ -22,7 +22,7 @@ To create a new endpoint, start by creating a new file in `src/api` called `i ```ts title=src/api/index.ts import { Router } from "express" -export default (rootDirectory, pluginOptions) => { +export default (rootDirectory, options) => { const router = Router() router.get("/hello", (req, res) => { @@ -38,7 +38,7 @@ export default (rootDirectory, pluginOptions) => { This exports a function that returns an Express router. The function receives two parameters: - `rootDirectory` is the absolute path to the root directory that your backend is running from. -- `pluginOptions` is an object that has your plugin's options. If your API route is not implemented in a plugin, then it will be an empty object. +- `options` is an object that contains the configurations exported from `medusa-config.js`. If your API route is part of a plugin, then it will contain the plugin's options instead. ### Defining Multiple Routes or Middlewares @@ -49,7 +49,7 @@ For example: ```ts title=src/api/index.ts import { Router } from "express" -export default (rootDirectory, pluginOptions) => { +export default (rootDirectory, options) => { const router = Router() router.get("/hello", (req, res) => { @@ -91,6 +91,79 @@ You can also create endpoints that don't reside under these two prefixes, simila --- +## Retrieve Medusa Config + +As mentioned, the second parameter `options` includes the configurations exported from `medusa-config.js`. However, in plugins it only includes the plugin's options. + +If you need to access the Medusa configuration in your endpoint, you can use the `getConfigFile` method imported from `medusa-core-utils`. It accepts the following parameters: + +1. `rootDirectory`: The first parameter is a string indicating root directory of your Medusa backend. +2. `config`: The second parameter is a string indicating the name of the config file, which should be `medusa-config` unless you change it. + +The function returns an object with the following properties: + +1. `configModule`: An object containing the configurations exported from `medusa-config.js`. +2. `configFilePath`: A string indicating absolute path to the configuration file. +3. `error`: if any errors occur, they'll be included as the value of this property. Otherwise, its value will be `undefined`. + +Here's an example of retrieving the configurations within an endpoint using `getConfigFile`: + +```ts title=src/api/index.ts +import { Router } from "express" +import { ConfigModule } from "@medusajs/medusa" +import { getConfigFile } from "medusa-core-utils" + +export default (rootDirectory) => { + const router = Router() + const { configModule } = getConfigFile( + rootDirectory, + "medusa-config" + ) + + router.get("/store-cors", (req, res) => { + res.json({ + store_cors: configModule.projectConfig.store_cors, + }) + }) + + return router +} +``` + +Notice that `getConfigFile` is a generic function. So, if you're using TypeScript, you should pass it the type `ConfigModule` imported from `@medusajs/medusa`. + +If you're accessing custom configurations, you'll need to create a new type that defines these configurations. For example: + +```ts title=src/api/index.ts +import { Router } from "express" +import { ConfigModule } from "@medusajs/medusa" +import { getConfigFile } from "medusa-core-utils" + +type MyConfigModule = ConfigModule & { + projectConfig: { + custom_config?: string + } +} + +export default (rootDirectory) => { + const router = Router() + const { configModule } = getConfigFile( + rootDirectory, + "medusa-config" + ) + + router.get("/hello", (req, res) => { + res.json({ + custom_config: configModule.projectConfig.custom_config, + }) + }) + + return router +} +``` + +--- + ## CORS Configuration If you’re adding a storefront or admin endpoint and you want to access these endpoints from the storefront or Medusa admin, you need to pass your endpoints Cross-Origin Resource Origin (CORS) options using the `cors` package. @@ -151,6 +224,42 @@ router.get("/admin/hello", cors(corsOptions), (req, res) => { --- +## Parse Request Body Parameters + +If you want to accept request body parameters, you need to pass express middlewares that parse the payload type to your router. + +For example: + +```ts +import bodyParser from "body-parser" +import express, { Router } from "express" + + +export default (rootDirectory, pluginOptions) => { + const router = Router() + + router.use(express.json()) + router.use(express.urlencoded({ extended: true })) + + router.post("/store/hello", (req, res) => { + res.json({ + message: req.body.name, + }) + }) + + return router +} +``` + +In the code snippet above, you use the following middlewares: + +- `express.json()`: parses requests with JSON payloads +- `express.urlencoded()`: parses requests with urlencoded payloads. + +You can learn about other available middlewares in the [Express documentation](https://expressjs.com/en/api.html#express). + +--- + ## Protected Routes Protected routes are routes that should be accessible by logged-in customers or users only. diff --git a/docs/content/development/events/create-subscriber.md b/docs/content/development/events/create-subscriber.md index 8216818b04..885b4e8ef0 100644 --- a/docs/content/development/events/create-subscriber.md +++ b/docs/content/development/events/create-subscriber.md @@ -54,6 +54,39 @@ eventBusService.subscribe("order.placed", this.handleOrder, { --- +## Retrieve Medusa Configurations + +Within your subscriber, you may need to access the Medusa configuration exported from `medusa-config.js`. To do that, you can access `configModule` using dependency injection. + +For example: + +```ts +import { ConfigModule, EventBusService } from "@medusajs/medusa" + +type InjectedDependencies = { + eventBusService: EventBusService + configModule: ConfigModule +} + +class OrderNotifierSubscriber { + protected readonly configModule_: ConfigModule + + constructor({ + eventBusService, + configModule, + }: InjectedDependencies) { + this.configModule_ = configModule + eventBusService.subscribe("order.placed", this.handleOrder) + } + + // ... +} + +export default OrderNotifierSubscriber +``` + +--- + ## Using Services in Subscribers You can access any service through the dependencies injected to your subscriber’s constructor. diff --git a/docs/content/development/services/create-service.mdx b/docs/content/development/services/create-service.mdx index ec873886b7..2b3e383f59 100644 --- a/docs/content/development/services/create-service.mdx +++ b/docs/content/development/services/create-service.mdx @@ -91,6 +91,42 @@ class HelloService extends TransactionBaseService { --- +## Retrieve Medusa Configurations + +Within your service, you may need to access the Medusa configuration exported from `medusa-config.js`. To do that, you can access `configModule` using dependency injection. + +For example: + +```ts +import { + ConfigModule, + TransactionBaseService, +} from "@medusajs/medusa" + +type InjectedDependencies = { + configModule: ConfigModule +} + +class HelloService extends TransactionBaseService { + protected readonly configModule_: ConfigModule + + constructor(container: InjectedDependencies) { + super(container) + this.configModule_ = container.configModule + } + + getConfigurations() { + return this.configModule_ + } + + // ... +} + +export default HelloService +``` + +--- + ## Use a Service In this section, you'll learn how to use services throughout your Medusa backend. This includes both Medusa's services and your custom services.