docs: added middleware documentation (#3000)

* docs: added a middleware documentation

* docs: fixes based on eslint
This commit is contained in:
Shahed Nasser
2023-01-11 20:15:17 +02:00
committed by GitHub
parent 76d6d26b3a
commit dd87e62536
5 changed files with 112 additions and 26 deletions
@@ -44,9 +44,12 @@ The batch job strategy class must extend the `AbstractBatchJobStrategy` class wh
For example, you can define the following class in the file you created: For example, you can define the following class in the file you created:
```typescript title=src/strategies/import.ts ```ts title=src/strategies/import.ts
import { AbstractBatchJobStrategy, BatchJobService } from '@medusajs/medusa' import {
import { EntityManager } from 'typeorm' AbstractBatchJobStrategy,
BatchJobService,
} from "@medusajs/medusa"
import { EntityManager } from "typeorm"
class MyImportStrategy extends AbstractBatchJobStrategy { class MyImportStrategy extends AbstractBatchJobStrategy {
protected batchJobService_: BatchJobService protected batchJobService_: BatchJobService
@@ -54,10 +57,10 @@ class MyImportStrategy extends AbstractBatchJobStrategy {
protected transactionManager_: EntityManager protected transactionManager_: EntityManager
processJob(batchJobId: string): Promise<void> { processJob(batchJobId: string): Promise<void> {
throw new Error('Method not implemented.') throw new Error("Method not implemented.")
} }
buildTemplate(): Promise<string> { buildTemplate(): Promise<string> {
throw new Error('Method not implemented.') throw new Error("Method not implemented.")
} }
} }
@@ -78,10 +81,10 @@ Since only one batch job strategy can handle a batch job type, you can overwrite
So, for example, to overwrite the product import strategy set the `batchType` property in your strategy to `product-import`: So, for example, to overwrite the product import strategy set the `batchType` property in your strategy to `product-import`:
```typescript ```ts
class MyImportStrategy extends AbstractBatchJobStrategy { class MyImportStrategy extends AbstractBatchJobStrategy {
static batchType = 'product-import' static batchType = "product-import"
//... // ...
} }
``` ```
@@ -0,0 +1,72 @@
# How to Add a Middleware
In this document, youll learn how to add a middleware to an existing or custom route in Medusa.
## Overview
As the Medusa server is built on top of [Express](https://expressjs.com/), Expresss features can be utilized during your development with Medusa.
One feature in particular is adding a [middleware](http://expressjs.com/en/guide/using-middleware.html#using-middleware). A middleware is a function that has access to the request and response objects.
A middleware can be used to perform an action when an endpoint is called or modify the response, among other usages.
You can add a middleware to an existing route in the Medusa server, a route in a plugin, or your custom routes.
---
## Add a Middleware
Adding a middleware is very similar to adding a custom endpoint. The middleware must be created either in the `src/api/index.ts` entry point, or other TypeScript or JavaScript files imported into `src/api/index.ts`.
:::info
Learn more about creating custom endpoints in [this documentation](./add.md).
:::
The following code snippet is an example of adding a middleware:
```ts title=src/api/index.ts
import { Router } from "express"
export default () => {
const router = Router()
router.use("/store/products", (req, res, next) => {
// / perform an action when retrieving products
next()
})
return router
}
```
This code snippet adds a middleware to the [List Products](/api/store/#tag/Product/operation/GetProducts) endpoint. In the middleware function, you can perform any action.
Then, you must call the `next` method received as a third parameter in the middleware function to ensure that the endpoint executes after the middleware.
:::info
You can learn more about Middlewares and their capabilities in [Expresss documentation](http://expressjs.com/en/guide/using-middleware.html#using-middleware).
:::
---
## Building Files
Similar to custom endpoints, you must transpile the files under `src` into the `dist` directory for the server to load them.
To do that, run the following command before running the Medusa server:
```bash npm2yarn
npm run build
```
---
## See Also
- [Create an Endpoint](./add.md)
- [Store API reference](/api/store)
- [Admin API reference](/api/admin)
@@ -295,6 +295,7 @@ npm run build
## See Also ## See Also
- [Add a Middleware](./add-middleware.md)
- [Storefront API Reference](/api/store) - [Storefront API Reference](/api/store)
- [Admin API Reference](/api/admin) - [Admin API Reference](/api/admin)
- [Create a Service](./../services/create-service.md). - [Create a Service](./../services/create-service.md).
@@ -12,46 +12,51 @@ If youre interested in learning what a price selection strategy is and how it
Create a TypeScript or JavaScript file in `src/strategies` of your Medusa server project with a class that extends the `AbstractPriceSelectionStrategy` class: Create a TypeScript or JavaScript file in `src/strategies` of your Medusa server project with a class that extends the `AbstractPriceSelectionStrategy` class:
```typescript title=src/strategies/price.ts ```ts title=src/strategies/price.ts
import { AbstractPriceSelectionStrategy, IPriceSelectionStrategy, PriceSelectionContext, PriceSelectionResult } from "@medusajs/medusa"; import {
AbstractPriceSelectionStrategy,
IPriceSelectionStrategy,
PriceSelectionContext,
PriceSelectionResult,
} from "@medusajs/medusa"
import { EntityManager } from "typeorm"; import { EntityManager } from "typeorm"
export default class MyPriceListStrategy extends AbstractPriceSelectionStrategy { export default class MyStrategy extends AbstractPriceSelectionStrategy {
withTransaction(manager: EntityManager): IPriceSelectionStrategy { withTransaction(manager: EntityManager): IPriceSelectionStrategy {
if (!manager) { if (!manager) {
return this return this
} }
return new MyPriceListStrategy() return new MyStrategy()
} }
async calculateVariantPrice( async calculateVariantPrice(
variant_id: string, variant_id: string,
context: PriceSelectionContext context: PriceSelectionContext
): Promise<PriceSelectionResult> { ): Promise<PriceSelectionResult> {
//TODO // TODO
} }
} }
``` ```
You can use services or repositories in the strategy by adding them to the constructor and updating the parameters passed to the `MyPriceListStrategy` constructor in `withTransaction`. For example: You can use services or repositories in the strategy by adding them to the constructor and updating the parameters passed to the `MyStrategy` constructor in `withTransaction`. For example:
```typescript ```ts
import { import {
AbstractPriceSelectionStrategy, AbstractPriceSelectionStrategy,
CustomerService, CustomerService,
IPriceSelectionStrategy, IPriceSelectionStrategy,
PriceSelectionContext, PriceSelectionContext,
PriceSelectionResult PriceSelectionResult,
} from "@medusajs/medusa"; } from "@medusajs/medusa"
export default class MyPriceListStrategy extends AbstractPriceSelectionStrategy { export default class MyStrategy extends AbstractPriceSelectionStrategy {
private customerService: CustomerService private customerService: CustomerService
constructor({ constructor({
customerService customerService,
}) { }) {
super() super()
this.customerService = customerService this.customerService = customerService
@@ -62,11 +67,11 @@ export default class MyPriceListStrategy extends AbstractPriceSelectionStrategy
return this return this
} }
return new MyPriceListStrategy({ return new MyStrategy({
customerService: this.customerService customerService: this.customerService,
}) })
} }
//... // ...
} }
``` ```
@@ -80,10 +85,10 @@ This method accepts the variant ID as a first parameter and the [context](./inde
This method must return an object having the following fields: This method must return an object having the following fields:
```typescript noReport ```ts noReport
{ {
originalPrice, //number | null originalPrice, // number | null
calculatedPrice, //number | null calculatedPrice, // number | null
prices // MoneyAmount[] prices // MoneyAmount[]
} }
``` ```
+5
View File
@@ -368,6 +368,11 @@ module.exports = {
id: "advanced/backend/endpoints/add", id: "advanced/backend/endpoints/add",
label: "Create an Endpoint" label: "Create an Endpoint"
}, },
{
type: "doc",
id: "advanced/backend/endpoints/add-middleware",
label: "Add a Middleware"
},
{ {
type: "doc", type: "doc",
id: "advanced/backend/services/create-service", id: "advanced/backend/services/create-service",