docs: added docs for how to Import Products using API (#2209)
* fix code snippet for create upload * added product import docs * fix to upload endpoint code example * added minimum version for MinIO
This commit is contained in:
1 parent
02c3b18466
commit
effa4248b6
4 files changed
+325
-4
No files matched your search
@@ -0,0 +1,306 @@
|
|||||||
|
import Tabs from '@theme/Tabs';
|
||||||
|
import TabItem from '@theme/TabItem';
|
||||||
|
|
||||||
|
# How to Import Products
|
||||||
|
|
||||||
|
In this document, you’ll learn how to use the Admin APIs to import products into a Medusa server.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Using Medusa’s [Batch Job Admin APIs](https://docs.medusajs.com/api/admin/#tag/Batch-Job), you can import products into your Medusa server. This will either add new products or update existing products.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
### Medusa Components
|
||||||
|
|
||||||
|
It is assumed that you already have a Medusa server installed and set up. If not, you can follow our [quickstart guide](../../quickstart/quick-start.md) to get started.
|
||||||
|
|
||||||
|
### Redis
|
||||||
|
|
||||||
|
Redis is required for batch jobs to work. Make sure you [install Redis](../../tutorial/0-set-up-your-development-environment.mdx#redis) and [configure it with your Medusa server](./../../usage/configurations.md#redis).
|
||||||
|
|
||||||
|
### File Service Plugin
|
||||||
|
|
||||||
|
Part of the process of importing products is uploading a CSV file. This requires a file service plugin to be installed on your server. If you don’t have any installed, you can install one of the following options:
|
||||||
|
|
||||||
|
- [MinIO](../../add-plugins/minio.md) (At least version `1.1.0`)
|
||||||
|
- [Spaces](../../add-plugins/spaces.md)
|
||||||
|
|
||||||
|
### CSV File
|
||||||
|
|
||||||
|
You must have a CSV file that you will use to import products into your Medusa server. You can check [this CSV example file](https://medusa-doc-files.s3.amazonaws.com/product-import-1.3.8.csv) to see which format is required for your import.
|
||||||
|
|
||||||
|
:::note
|
||||||
|
|
||||||
|
If you have Sales Channels enabled on your server, you must use [this CSV example file](https://medusa-doc-files.s3.amazonaws.com/product-import-sales-channels.csv) instead.
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
### JS Client
|
||||||
|
|
||||||
|
This guide includes code snippets to send requests to your Medusa server using Medusa’s JS Client, JavaScript’s Fetch API, or cURL.
|
||||||
|
|
||||||
|
If you follow the JS Client code blocks, it’s assumed you already have [Medusa’s JS Client](../../js-client/overview.md) installed and have [created an instance of the client](../../js-client/overview.md#configuration).
|
||||||
|
|
||||||
|
### Authenticated Admin User
|
||||||
|
|
||||||
|
You must be an authenticated admin user before following along with the steps in the tutorial.
|
||||||
|
|
||||||
|
You can learn more about [authenticating as an admin user in the API reference](https://docs.medusajs.com/api/admin/#section/Authentication).
|
||||||
|
|
||||||
|
## 1. Upload CSV File
|
||||||
|
|
||||||
|
The first step is to upload the CSV file that you want to import products.
|
||||||
|
|
||||||
|
You can do that by sending the following request to the [Upload Files](https://docs.medusajs.com/api/admin/#tag/Upload/operation/PostUploads) endpoint:
|
||||||
|
|
||||||
|
<Tabs groupId="request-type">
|
||||||
|
<TabItem value="client" label="Medusa JS Client" default>
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
// using JS Client
|
||||||
|
medusa.admin.uploads.create(file) //file is an instance of File
|
||||||
|
.then(({ uploads }) => {
|
||||||
|
const key = uploads[0].key;
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="fetch" label="Fetch API">
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
// using Fetch API
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('files', file); //file is an instance of File
|
||||||
|
|
||||||
|
fetch(`<YOUR_SERVER>/admin/uploads`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'multipart/form-data',
|
||||||
|
},
|
||||||
|
body: formData
|
||||||
|
})
|
||||||
|
.then((response) => response.json())
|
||||||
|
.then(({ uploads }) => {
|
||||||
|
const key = uploads[0].key;
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="curl" label="cURL">
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# using cURL
|
||||||
|
curl --location --request POST '<YOUR_SERVER>/admin/uploads' \
|
||||||
|
--header 'Authorization: Bearer {api_token}' \
|
||||||
|
--header 'Content-Type: text/csv' \
|
||||||
|
--form 'files=@"<FILE_PATH_1>"'
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
|
This request returns an array of uploads. Each item in the array is an object that includes the properties `url` and `key`. You’ll need the `key` to import the products next.
|
||||||
|
|
||||||
|
## 2. Create a Batch Job for Product Import
|
||||||
|
|
||||||
|
To start a new product import, you must create a batch job.
|
||||||
|
|
||||||
|
You can do that by sending the following request to the [Create a Batch Job](https://docs.medusajs.com/api/admin/#tag/Batch-Job/operation/PostBatchJobs) endpoint:
|
||||||
|
|
||||||
|
<Tabs groupId="request-type">
|
||||||
|
<TabItem value="client" label="Medusa JS Client" default>
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
// using JS Client
|
||||||
|
medusa.admin.batchJobs.create({
|
||||||
|
type: 'product-import',
|
||||||
|
context: {
|
||||||
|
fileKey: key //obtained from previous step
|
||||||
|
},
|
||||||
|
dry_run: true
|
||||||
|
})
|
||||||
|
.then(( batch_job ) => {
|
||||||
|
console.log(batch_job.status);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="fetch" label="Fetch API">
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
// using Fetch API
|
||||||
|
fetch(`<YOUR_SERVER>/admin/batch-jobs`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
type: 'product-import',
|
||||||
|
context: {
|
||||||
|
fileKey: key //obtained from previous step
|
||||||
|
},
|
||||||
|
dry_run: true
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then((response) => response.json())
|
||||||
|
.then(({ batch_job }) => {
|
||||||
|
console.log(batch_job.status);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="curl" label="cURL">
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# using cURL
|
||||||
|
curl --location --request POST '<YOUR_SERVER>/admin/batch-jobs' \
|
||||||
|
--header 'Authorization: Bearer {api_token}' \
|
||||||
|
--header 'Content-Type: application/json' \
|
||||||
|
--data-raw '{
|
||||||
|
"type": "product-import",
|
||||||
|
"context": {
|
||||||
|
"fileKey": "<KEY>"
|
||||||
|
},
|
||||||
|
"dry_run": true
|
||||||
|
}'
|
||||||
|
# <KEY> is the key you obtained from the previous step
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
|
In the body of the request, you must pass the following parameters:
|
||||||
|
|
||||||
|
- `type`: Batch jobs can be of different types. For product imports, the type should always be `product-import`.
|
||||||
|
- `context`: An object that must contain the `fileKey` property. The value of this property is the key received when you uploaded the CSV file.
|
||||||
|
- `dry_run`: This is optional to include. If not set or if its value is `false`, the product import will start right after you send this request. Settings its value to `true` allows you to retrieve afterward a brief of the number of products that will be added or updated, or the number of rejected products.
|
||||||
|
|
||||||
|
This request returns the batch job with its details such as the `status` or `id`.
|
||||||
|
|
||||||
|
:::note
|
||||||
|
|
||||||
|
If you don’t set `dry_run` or you set it to `false`, you don’t need to follow the rest of these steps.
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
## (Optional) Retrieve Batch Job
|
||||||
|
|
||||||
|
After creating the batch job, it will be pre-processed. At this point, the CSV file will be validated, and the number of products to add and update, or that are rejected are counted.
|
||||||
|
|
||||||
|
You can retrieve all the details of the batch job, including its status and the brief statistics related to the products by sending the following request:
|
||||||
|
|
||||||
|
<Tabs groupId="request-type">
|
||||||
|
<TabItem value="client" label="Medusa JS Client" default>
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
// using JS Client
|
||||||
|
medusa.admin.batchJobs.retrieve(batchJobId)
|
||||||
|
.then(( batch_job ) => {
|
||||||
|
console.log(batch_job.status, batch_job.result);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="fetch" label="Fetch API">
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
// using Fetch API
|
||||||
|
fetch(`<YOUR_SERVER>/admin/batch-jobs/${batchJobId}`)
|
||||||
|
.then((response) => response.json())
|
||||||
|
.then(({ batch_job }) => {
|
||||||
|
console.log(batch_job.status, batch_job.result);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="curl" label="cURL">
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# using cURL
|
||||||
|
curl --location --request GET '<YOUR_SERVER>/admin/batch-jobs/<BATCH_JOB_ID>' \
|
||||||
|
--header 'Authorization: Bearer {api_token}'
|
||||||
|
# <BATCH_JOB_ID> is the ID of the batch job
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
|
This request accepts the batch job’s ID as a parameter, which can be retrieved from the previous request. It returns the batch job in the response.
|
||||||
|
|
||||||
|
If the batch job has been pre-processed, the status of the batch job will be `pre_processed` and the `result` property will contain details about the import.
|
||||||
|
|
||||||
|
Here’s an example of the `result` property:
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
"result": {
|
||||||
|
"count": 5, // Total number of products to be created or updated
|
||||||
|
"stat_descriptors": [ //details about the products to be created/updated
|
||||||
|
{
|
||||||
|
"key": "product-import-count",
|
||||||
|
"name": "Products/variants to import",
|
||||||
|
"message": "There will be 2 products created (0 updated).\n 3 variants will be created and 0 updated"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"advancement_count": 0 //number of products processed so far. Will be 0 before the import is confirmed.
|
||||||
|
},
|
||||||
|
```
|
||||||
|
|
||||||
|
## 3. Confirm Batch Job
|
||||||
|
|
||||||
|
A batch job can be confirmed only once the batch job has the status `pre_processed`. Once you confirm a batch job, the product import will start which will create or update products on your server.
|
||||||
|
|
||||||
|
To confirm a batch job send the following request:
|
||||||
|
|
||||||
|
<Tabs groupId="request-type">
|
||||||
|
<TabItem value="client" label="Medusa JS Client" default>
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
// using JS Client
|
||||||
|
medusa.admin.batchJobs.confirm(batchJobId)
|
||||||
|
.then(( batch_job ) => {
|
||||||
|
console.log(batch_job.status);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="fetch" label="Fetch API">
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
// using Fetch API
|
||||||
|
fetch(`<YOUR_SERVER>/admin/batch-jobs/${batchJobId}/confirm`, {
|
||||||
|
method: 'POST'
|
||||||
|
})
|
||||||
|
.then((response) => response.json())
|
||||||
|
.then(({ batch_job }) => {
|
||||||
|
console.log(batch_job.status);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="curl" label="cURL">
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# using cURL
|
||||||
|
curl --location --request POST '<YOUR_SERVER>/admin/batch-jobs/<BATCH_JOB_ID>/confirm' \
|
||||||
|
--header 'Authorization: Bearer {api_token}'
|
||||||
|
# <BATCH_JOB_ID> is the ID of the batch job
|
||||||
|
```
|
||||||
|
|
||||||
|
</TabItem>
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
|
This request accepts the ID of the batch job as a path parameter and returns the updated batch job. The returned batch job should have the status `confirmed`, which indicates that the batch job will now start processing.
|
||||||
|
|
||||||
|
### Checking the Status After Confirmation
|
||||||
|
|
||||||
|
After confirming the batch job, you can check the status while it is processing at any given point by [retrieving the batch job](#optional-retrieve-batch-job). Based on the status, you can infer the progress of the batch job:
|
||||||
|
|
||||||
|
- If the status is `processing`, it means that the import is currently in progress. You can also check `result.advancement_count` to find out how many products have been created or updated so far.
|
||||||
|
- If the status is `failed`, it means an error has occurred during the import. You can check the error in `result.errors`.
|
||||||
|
- If the status is `completed`, it means the import has finished successfully.
|
||||||
|
|
||||||
|
## What’s Next 🚀
|
||||||
|
|
||||||
|
- Learn more about [Batch Jobs and how they work](../backend/batch-jobs/index.md).
|
||||||
|
- Check out the [Batch Jobs API Reference](https://docs.medusajs.com/api/admin/#tag/Batch-Job).
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
import Tabs from '@theme/Tabs';
|
||||||
|
import TabItem from '@theme/TabItem';
|
||||||
|
|
||||||
# How to Implement Checkout Flow
|
# How to Implement Checkout Flow
|
||||||
|
|
||||||
This document will guide you through the steps needed to implement the checkout flow in a Medusa storefront, including steps related to adding a custom payment provider.
|
This document will guide you through the steps needed to implement the checkout flow in a Medusa storefront, including steps related to adding a custom payment provider.
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ import fs from "fs"
|
|||||||
/**
|
/**
|
||||||
* @oas [post] /uploads
|
* @oas [post] /uploads
|
||||||
* operationId: "PostUploads"
|
* operationId: "PostUploads"
|
||||||
* summary: "Upload a file"
|
* summary: "Upload files"
|
||||||
* description: "Uploads a file to the specific fileservice that is installed in Medusa."
|
* description: "Uploads at least one file to the specific fileservice that is installed in Medusa."
|
||||||
* x-authenticated: true
|
* x-authenticated: true
|
||||||
* requestBody:
|
* requestBody:
|
||||||
* content:
|
* content:
|
||||||
@@ -32,7 +32,8 @@ import fs from "fs"
|
|||||||
* curl --location --request POST 'https://medusa-url.com/admin/uploads' \
|
* curl --location --request POST 'https://medusa-url.com/admin/uploads' \
|
||||||
* --header 'Authorization: Bearer {api_token}' \
|
* --header 'Authorization: Bearer {api_token}' \
|
||||||
* --header 'Content-Type: image/jpeg' \
|
* --header 'Content-Type: image/jpeg' \
|
||||||
* --data-binary '{file_path}'
|
* --form 'files=@"<FILE_PATH_1>"' \
|
||||||
|
* --form 'files=@"<FILE_PATH_1>"'
|
||||||
* security:
|
* security:
|
||||||
* - api_token: []
|
* - api_token: []
|
||||||
* - cookie_auth: []
|
* - cookie_auth: []
|
||||||
|
|||||||
+12
-1
@@ -252,7 +252,18 @@ module.exports = {
|
|||||||
label: "Implement Checkout"
|
label: "Implement Checkout"
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
type: "category",
|
||||||
|
label: "Admin",
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
type: "doc",
|
||||||
|
id: "advanced/admin/import-products",
|
||||||
|
label: "Import Products"
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in new issue
Block a user