docs: added documentation pages for experimental features (#5671)
* docs: added documentation pages for experimental features * fix content lint issues * fixed lint errors * added migration step * added workflows introduction * add installation guides * added installation guides for modules + generated workflows reference * added missing workflows reference link * Added warning message for experimental features * fix note
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
# Examples of Product Module
|
||||
|
||||
In this document, you’ll find common examples of how you can use the Product module in your application.
|
||||
|
||||
:::note
|
||||
|
||||
Examples in this section are in the context of a Next.js App Router.
|
||||
|
||||
:::
|
||||
|
||||
## Create Product
|
||||
|
||||
```ts
|
||||
import { NextResponse } from "next/server"
|
||||
|
||||
import {
|
||||
initialize as initializeProductModule,
|
||||
} from "@medusajs/product"
|
||||
|
||||
export async function POST(request: Request) {
|
||||
const productService = await initializeProductModule()
|
||||
|
||||
const products = await productService.create([
|
||||
{
|
||||
title: "Medusa Shirt",
|
||||
options: [
|
||||
{
|
||||
title: "Color",
|
||||
},
|
||||
],
|
||||
variants: [
|
||||
{
|
||||
title: "Black Shirt",
|
||||
options: [
|
||||
{
|
||||
value: "Black",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
])
|
||||
|
||||
return NextResponse.json({ products })
|
||||
}
|
||||
```
|
||||
|
||||
## List Products
|
||||
|
||||
```ts
|
||||
import { NextResponse } from "next/server"
|
||||
|
||||
import {
|
||||
initialize as initializeProductModule,
|
||||
} from "@medusajs/product"
|
||||
|
||||
export async function GET(request: Request) {
|
||||
const productService = await initializeProductModule()
|
||||
|
||||
const data = await productService.list()
|
||||
|
||||
return NextResponse.json({ products: data })
|
||||
}
|
||||
```
|
||||
|
||||
## Retrieve a Product by its ID
|
||||
|
||||
```ts
|
||||
import { NextResponse } from "next/server"
|
||||
|
||||
import {
|
||||
initialize as initializeProductModule,
|
||||
} from "@medusajs/product"
|
||||
|
||||
export async function GET(
|
||||
request: Request,
|
||||
{ params }: { params: Record<string, any> }) {
|
||||
|
||||
const { id } = params
|
||||
const productService = await initializeProductModule()
|
||||
|
||||
const data = await productService.list({
|
||||
id,
|
||||
})
|
||||
|
||||
return NextResponse.json({ product: data[0] })
|
||||
}
|
||||
```
|
||||
|
||||
## Retrieve a Product by its Handle
|
||||
|
||||
```ts
|
||||
import { NextResponse } from "next/server"
|
||||
|
||||
import {
|
||||
initialize as initializeProductModule,
|
||||
} from "@medusajs/product"
|
||||
|
||||
export async function GET(
|
||||
request: Request,
|
||||
{ params }: { params: Record<string, any> }) {
|
||||
|
||||
const { handle } = params
|
||||
const productService = await initializeProductModule()
|
||||
|
||||
const data = await productService.list({
|
||||
handle,
|
||||
})
|
||||
|
||||
return NextResponse.json({ product: data[0] })
|
||||
}
|
||||
```
|
||||
|
||||
## Retrieve Categories
|
||||
|
||||
```ts
|
||||
import { NextResponse } from "next/server"
|
||||
|
||||
import {
|
||||
initialize as initializeProductModule,
|
||||
} from "@medusajs/product"
|
||||
|
||||
export async function GET(request: Request) {
|
||||
const productService = await initializeProductModule()
|
||||
|
||||
const data = await productService.listCategories()
|
||||
|
||||
return NextResponse.json({ categories: data })
|
||||
}
|
||||
```
|
||||
|
||||
## Retrieve Category by Handle
|
||||
|
||||
```ts
|
||||
import { NextResponse } from "next/server"
|
||||
|
||||
import {
|
||||
initialize as initializeProductModule,
|
||||
} from "@medusajs/product"
|
||||
|
||||
export async function GET(
|
||||
request: Request,
|
||||
{ params }: { params: Record<string, any> }) {
|
||||
|
||||
const { handle } = params
|
||||
const productService = await initializeProductModule()
|
||||
|
||||
const data = await productService.listCategories({
|
||||
handle,
|
||||
})
|
||||
|
||||
return NextResponse.json({ category: data[0] })
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## More Examples
|
||||
|
||||
The [module interface reference](../../references/product/interfaces/IProductModuleService.mdx) provides a reference to all the methods available for use with examples for each.
|
||||
@@ -0,0 +1,164 @@
|
||||
import DocCard from '@theme/DocCard'
|
||||
import Icons from '@theme/Icon'
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# Install Product Module in Medusa
|
||||
|
||||
In this document, you'll learn how to install the Product module using NPM in the Medusa backend.
|
||||
|
||||
## Step 1: Install Module
|
||||
|
||||
To install the Product module, run the following command in the root directory of the Medusa backend:
|
||||
|
||||
```bash npm2yarn
|
||||
npm install @medusajs/product
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 2: Add Module to Configurations
|
||||
|
||||
In `medusa-config.js`, add the product module to the exported object under the `modules` property:
|
||||
|
||||
```js title=medusa-config.js
|
||||
module.exports = {
|
||||
// ...
|
||||
modules: {
|
||||
// ...
|
||||
productService: {
|
||||
resolve: "@medusajs/product",
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 3: Run Migrations
|
||||
|
||||
Run the following command to reflect schema changes into your database:
|
||||
|
||||
```bash
|
||||
npx medusa migrations run
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Use the Module
|
||||
|
||||
You can now start using the module's `ProductModuleService` by resolving it through [dependency injection](../../development/fundamentals/dependency-injection.md).
|
||||
|
||||
For example:
|
||||
|
||||
<Tabs groupId="resource-type" isCodeTabs={true}>
|
||||
<TabItem value="api-route" label="API Route" attributes={{
|
||||
title: "src/api/store/custom/route.ts"
|
||||
}} default>
|
||||
|
||||
```ts
|
||||
import type {
|
||||
MedusaRequest,
|
||||
MedusaResponse
|
||||
} from "@medusajs/medusa";
|
||||
import {
|
||||
ProductModuleService
|
||||
} from "@medusajs/product"
|
||||
|
||||
export async function GET(
|
||||
req: MedusaRequest,
|
||||
res: MedusaResponse
|
||||
) {
|
||||
const productModuleService = req.scope.resolve(
|
||||
"productModuleService"
|
||||
)
|
||||
|
||||
return res.json({
|
||||
products: productModuleService.list()
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="subscribers" label="Subscribers" attributes={{
|
||||
title: "src/subscribers/create-customer.ts"
|
||||
}}>
|
||||
|
||||
```ts
|
||||
import {
|
||||
type SubscriberConfig,
|
||||
type SubscriberArgs,
|
||||
ProductService,
|
||||
} from "@medusajs/medusa"
|
||||
import {
|
||||
ProductModuleService
|
||||
} from "@medusajs/product"
|
||||
|
||||
export default async function handleListProducts({
|
||||
data, eventName, container, pluginOptions
|
||||
}: SubscriberArgs<Customer>) {
|
||||
const productModuleService = container.resolve(
|
||||
"productModuleService"
|
||||
)
|
||||
|
||||
console.log(await productModuleService.list())
|
||||
}
|
||||
|
||||
export const config: SubscriberConfig = {
|
||||
event: ProductService.Events.CREATED,
|
||||
context: {
|
||||
subscriberId: "list-products"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="service" label="Service" attributes={{
|
||||
title: "src/service/hello.ts"
|
||||
}}>
|
||||
|
||||
```ts
|
||||
import { TransactionBaseService } from "@medusajs/medusa"
|
||||
import {
|
||||
ProductModuleService
|
||||
} from "@medusajs/product"
|
||||
|
||||
class HelloService extends TransactionBaseService {
|
||||
private productModuleService: ProductModuleService
|
||||
|
||||
constructor(container) {
|
||||
super(container)
|
||||
this.productModuleService = container.productModuleService
|
||||
}
|
||||
|
||||
await listProducts() {
|
||||
return await this.productModuleService.list()
|
||||
}
|
||||
}
|
||||
|
||||
export default HelloService
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
:::tip
|
||||
|
||||
In the Examples or API Reference guides, you may see an initialization of the product module. This is only necessary if you're using the module outside the Medusa backend.
|
||||
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
## Up Next
|
||||
|
||||
<DocCard item={{
|
||||
type: 'link',
|
||||
href: '/references/product',
|
||||
label: 'Service Interface Reference',
|
||||
customProps: {
|
||||
icon: Icons['academic-cap-solid'],
|
||||
description: 'Find a full reference of the module\' service interface\s methods.'
|
||||
}
|
||||
}}
|
||||
/>
|
||||
@@ -0,0 +1,198 @@
|
||||
# Install in Node.js-Based Application
|
||||
|
||||
In this document, you’ll learn how to setup and use the Product module in a Node.js based application.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before installing the Product module in your application, make sure you have the following prerequisites:
|
||||
|
||||
- Node.js v16 or greater
|
||||
- PostgreSQL database. You can use an existing Medusa database, or set up a new PostgreSQL database.
|
||||
|
||||
---
|
||||
|
||||
## Install Package
|
||||
|
||||
In your Node.js-based applications, such as a Next.js application, you can install the Product module with the following command:
|
||||
|
||||
```bash npm2yarn
|
||||
npm install @medusajs/product
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Add Database Configuration
|
||||
|
||||
Add the following environment variable to your application:
|
||||
|
||||
```bash
|
||||
POSTGRES_URL=<DATABASE_URL>
|
||||
```
|
||||
|
||||
Where `<DATABASE_URL>` is your database connection URL of the format `postgres://[user][:password]@[host][:port]/[dbname]`. You can learn more about the connection URL format in [this guide](https://www.notion.so/development/backend/configurations.md#database_url).
|
||||
|
||||
You can also set the following optional environment variables:
|
||||
|
||||
- `POSTGRES_SCHEMA`: a string indicating the PostgreSQL schema to use. By default, it's `public`.
|
||||
- `POSTGRES_DRIVER_OPTIONS`: a stringified JSON object indicating the PostgreSQL options to use. The JSON object is then parsed to be used as a JavaScript object. By default, it's `{"connection":{"ssl":false}}` for local PostgreSQL databases, and `{"connection":{"ssl":{"rejectUnauthorized":false}}}` for remote databases.
|
||||
|
||||
:::note
|
||||
|
||||
If `POSTGRES_DRIVER_OPTIONS` is not specified, the PostgreSQL database is considered local if `POSTGRES_URL` includes `localhost`. Otherwise, it's considered remote.
|
||||
|
||||
:::
|
||||
|
||||
### Run Database Migrations
|
||||
|
||||
:::note
|
||||
|
||||
You can skip this step if you use an existing Medusa database.
|
||||
|
||||
:::
|
||||
|
||||
Migrations are used to create your database schema. Before you can run migrations, add in your `package.json` the following scripts:
|
||||
|
||||
```json
|
||||
"scripts": {
|
||||
//...other scripts
|
||||
"product:migrations:run": "medusa-product-migrations-up",
|
||||
"product:seed": "medusa-product-seed ./seed-data.js"
|
||||
}
|
||||
```
|
||||
|
||||
The first command runs the migrations, and the second command allows you to seed your database with demo products optionally.
|
||||
|
||||
However, you’d need the following seed file added to the root of your project directory:
|
||||
|
||||
<Details>
|
||||
<Summary>Seed File</Summary>
|
||||
|
||||
```js
|
||||
const productCategoriesData = [
|
||||
{
|
||||
id: "category-0",
|
||||
name: "category 0",
|
||||
parent_category_id: null,
|
||||
},
|
||||
{
|
||||
id: "category-1",
|
||||
name: "category 1",
|
||||
parent_category_id: "category-0",
|
||||
},
|
||||
{
|
||||
id: "category-1-a",
|
||||
name: "category 1 a",
|
||||
parent_category_id: "category-1",
|
||||
},
|
||||
{
|
||||
id: "category-1-b",
|
||||
name: "category 1 b",
|
||||
parent_category_id: "category-1",
|
||||
is_internal: true,
|
||||
},
|
||||
{
|
||||
id: "category-1-b-1",
|
||||
name: "category 1 b 1",
|
||||
parent_category_id: "category-1-b",
|
||||
},
|
||||
]
|
||||
|
||||
const productsData = [
|
||||
{
|
||||
id: "test-1",
|
||||
title: "product 1",
|
||||
status: "published",
|
||||
descriptions: "Lorem ipsum dolor sit amet, consectetur.",
|
||||
tags: [
|
||||
{
|
||||
id: "tag-1",
|
||||
value: "France",
|
||||
},
|
||||
],
|
||||
categories: [
|
||||
{
|
||||
id: "category-0",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "test-2",
|
||||
title: "product",
|
||||
status: "published",
|
||||
descriptions: "Lorem ipsum dolor sit amet, consectetur.",
|
||||
tags: [
|
||||
{
|
||||
id: "tag-2",
|
||||
value: "Germany",
|
||||
},
|
||||
],
|
||||
categories: [
|
||||
{
|
||||
id: "category-1",
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
const variantsData = [
|
||||
{
|
||||
id: "test-1",
|
||||
title: "variant title",
|
||||
sku: "sku 1",
|
||||
product: { id: productsData[0].id },
|
||||
inventory_quantity: 10,
|
||||
},
|
||||
{
|
||||
id: "test-2",
|
||||
title: "variant title",
|
||||
sku: "sku 2",
|
||||
product: { id: productsData[1].id },
|
||||
inventory_quantity: 10,
|
||||
},
|
||||
]
|
||||
|
||||
module.exports = {
|
||||
productCategoriesData,
|
||||
productsData,
|
||||
variantsData,
|
||||
}
|
||||
```
|
||||
|
||||
</Details>
|
||||
|
||||
Then run the commands you added to migrate the database schema and optionally seed data:
|
||||
|
||||
```bash npm2yarn
|
||||
npm run product:migrations:run
|
||||
# optionally
|
||||
npm run product:seed
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Next.js Application: Adjust Configurations
|
||||
|
||||
The Product module uses dependencies that aren’t Webpack optimized. Since Next.js uses Webpack for compilation, you need to add the Product module as an external dependency.
|
||||
|
||||
To do that, add the `serverComponentsExternalPackages` option in `next.config.js`:
|
||||
|
||||
```js title=next.config.js
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {
|
||||
experimental: {
|
||||
serverComponentsExternalPackages: [
|
||||
"@medusajs/product",
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
module.exports = nextConfig
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Start Development
|
||||
|
||||
You can refer to the [Example Usages documentation page](./examples.md) for examples of using the Product module.
|
||||
|
||||
You can also refer to the [Module Interface Reference](../../references/product/interfaces/IProductModuleService.mdx) for a detailed reference on all available methods.
|
||||
@@ -0,0 +1,81 @@
|
||||
import DocCard from '@theme/DocCard'
|
||||
import Icons from '@theme/Icon'
|
||||
|
||||
# Product Module Overview
|
||||
|
||||
The Product module is the `@medusajs/product` NPM package that provides product-related features in your Medusa and Node.js applications. It can be used to store products with variants, organize them into categories and collections, and more.
|
||||
|
||||
## Features
|
||||
|
||||
### Products Management
|
||||
|
||||
With the Product module, you can store products and manage them through the main interface methods. Products can have custom options, such as color or size, and each variant in the product sets the value for these options.
|
||||
|
||||
```ts
|
||||
const products = await productService.create([
|
||||
{
|
||||
title: "Medusa Shirt",
|
||||
options: [
|
||||
{
|
||||
title: "Color",
|
||||
},
|
||||
],
|
||||
variants: [
|
||||
{
|
||||
title: "Black Shirt",
|
||||
options: [
|
||||
{
|
||||
value: "Black",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
])
|
||||
```
|
||||
|
||||
### Product Organizations
|
||||
|
||||
The Product module provides different entities that can be used to organize products, including categories, collections, tags, and more.
|
||||
|
||||
```ts
|
||||
const category = await productService.createCategory({
|
||||
name: "Shirts",
|
||||
})
|
||||
|
||||
const products = await productService.update([
|
||||
{
|
||||
id: product.id,
|
||||
categories: [
|
||||
{
|
||||
id: category.id,
|
||||
},
|
||||
],
|
||||
},
|
||||
])
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## How to Use the Product Module
|
||||
|
||||
The Product Module can be used in many use cases, including:
|
||||
|
||||
- Medusa Backend: The Medusa backend uses the product module to implement some product features. However, it's guarded by the [experimental feature flag](../index.md#enabling-experimental-features). If you want to use the product module in your backend's customizations, follow [this installation guide](./install-medusa.mdx).
|
||||
- Serverless Application: Use the Product Module in a serverless application, such as a Next.js application, without having to manage a fully-fledged ecommerce system. You can use it by [installing it in your Node.js project as an NPM package](./install-nodejs.md).
|
||||
- Node.js Application: Use the Product Module in any Node.js application. Follow [this guide](./install-nodejs.md) to learn how to install it.
|
||||
|
||||
---
|
||||
|
||||
## Up Next
|
||||
|
||||
<DocCard item={{
|
||||
type: 'link',
|
||||
href: '/experimental/product/examples',
|
||||
label: 'Example Usages',
|
||||
customProps: {
|
||||
icon: Icons['academic-cap-solid'],
|
||||
description: 'Find examples of common usages of the module\'s interface.'
|
||||
}
|
||||
}}
|
||||
/>
|
||||
Reference in New Issue
Block a user