docs: document JSON properties (#13099)
This commit is contained in:
@@ -0,0 +1,237 @@
|
||||
export const metadata = {
|
||||
title: `${pageNumber} JSON Properties in Data Models`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
In this chapter, you'll learn how to use and manage [JSON properties](../properties/page.mdx#json) in data models.
|
||||
|
||||
## What is a JSON Property?
|
||||
|
||||
A JSON property in a data model is a flexible object that can contain various types of values.
|
||||
|
||||
For example, you can create a `Brand` data model with a `metadata` JSON property to store additional information about the brand:
|
||||
|
||||
```ts highlights={[["6"]]}
|
||||
import { model } from "@medusajs/framework/utils"
|
||||
|
||||
const Brand = model.define("brand", {
|
||||
id: model.id().primaryKey(),
|
||||
name: model.text(),
|
||||
metadata: model.json(),
|
||||
})
|
||||
```
|
||||
|
||||
### Accepted Values in JSON Property
|
||||
|
||||
JSON properties are made up of key-value pairs. The keys are strings, and the values can be one of the following types:
|
||||
|
||||
- **Strings**: Text values.
|
||||
- Empty strings remove the property from the JSON object. Learn more in the [Remove a Property from the JSON Property](#remove-a-property-from-the-json-property) section.
|
||||
- **Numbers**: Numeric values.
|
||||
- **Booleans**: `true` or `false` values.
|
||||
- **Nested Objects**: Objects within objects.
|
||||
- **Arrays**: Lists of values of any of the above types.
|
||||
|
||||
For example, a `metadata` JSON property can look like this:
|
||||
|
||||
```json
|
||||
{
|
||||
"category": "electronics",
|
||||
"views": 1500,
|
||||
"is_featured": true,
|
||||
"tags": ["new", "sale"],
|
||||
"details": {
|
||||
"warranty": "2 years",
|
||||
"origin": "USA"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### What are JSON Properties Useful For?
|
||||
|
||||
JSON properties allow you to store flexible and dynamic data structures that can evolve over time without requiring changes to the database schema.
|
||||
|
||||
Most data models in Medusa's Commerce Modules have a `metadata` property that is a JSON object. `metadata` allows you to store custom information that is not part of the core data model.
|
||||
|
||||
Some examples of data to store in JSON properties:
|
||||
|
||||
- Custom gift message for line items in an order.
|
||||
- Product's ID in a third-party system.
|
||||
- Brand's category or tags.
|
||||
|
||||
### What are JSON Properties Not Useful For?
|
||||
|
||||
JSON properties are not suitable for structured data that requires strict validation or relationships with other data models.
|
||||
|
||||
For example, if you want to re-use brands across different products, it's better to create a `Brand` data model and [define a link](../../module-links/page.mdx) to the `Product` data model instead of storing brand information in the product's `metadata` JSON property.
|
||||
|
||||
---
|
||||
|
||||
## How to Manage JSON Properties?
|
||||
|
||||
### How Medusa Updates JSON Properties
|
||||
|
||||
Consider a Brand Module with a `Brand` data model as shown [in the previous section](#what-are-json-properties). The [module's service](../../modules/page.mdx#2-create-service) will extend `MedusaService`, which generates methods like [updateBrands](!resources!/service-factory-reference/methods/update) to update a brand.
|
||||
|
||||
When you pass a JSON property in the `updateBrands` method, Medusa will merge the provided JSON object with the existing one in the database. So, only the properties you pass will be updated, and the rest will remain unchanged.
|
||||
|
||||
The following sections show examples of how to add, update, and remove properties in a JSON property.
|
||||
|
||||
<Note title="Prerequisite" forceMultiline>
|
||||
|
||||
The following examples assume you have a `brandModuleService` that is resolved from the [Medusa container](../../medusa-container/page.mdx). For example:
|
||||
|
||||
```ts
|
||||
const brandModuleService = container.resolve(BRAND_MODULE)
|
||||
```
|
||||
|
||||
</Note>
|
||||
|
||||
### Add a Property to the JSON Property
|
||||
|
||||
Continuing with the Brand example, to add a `category` property to the `metadata` property, pass the new property in the `update` or `create` methods:
|
||||
|
||||
```ts
|
||||
const brand = await brandModuleService.updateBrands({
|
||||
id: "brand_123",
|
||||
metadata: {
|
||||
category: "electronics",
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
The brand record will now have the `metadata` property updated to include the new `category` property:
|
||||
|
||||
```json title="Result"
|
||||
{
|
||||
"id": "brand_123",
|
||||
"metadata": {
|
||||
"category": "electronics"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If you want to add another `is_featured` property later, you can do so by passing it in the update method again without affecting the existing properties:
|
||||
|
||||
```ts
|
||||
const brand = await brandModuleService.updateBrands({
|
||||
id: "brand_123",
|
||||
metadata: {
|
||||
is_featured: true,
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
The brand record will now have the `metadata` property updated to include both `category` and `is_featured` properties:
|
||||
|
||||
```json title="Result"
|
||||
{
|
||||
"id": "brand_123",
|
||||
"metadata": {
|
||||
"category": "electronics",
|
||||
"is_featured": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Update an Existing Property in the JSON Property
|
||||
|
||||
To update an existing property in the JSON property, pass the updated value in the `update` method.
|
||||
|
||||
Continuing with the Brand example, to update the `category` property in the `metadata`:
|
||||
|
||||
```ts
|
||||
const brand = await brandModuleService.updateBrands({
|
||||
id: "brand_123",
|
||||
metadata: {
|
||||
category: "home appliances",
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
The brand record will now have the `metadata` property updated to reflect the new `category` value, and existing properties will remain unchanged:
|
||||
|
||||
```json title="Result"
|
||||
{
|
||||
"id": "brand_123",
|
||||
"metadata": {
|
||||
"category": "home appliances",
|
||||
"is_featured": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Caveat: Updating Nested Objects
|
||||
|
||||
If you want to update a nested object within the JSON property, you need to provide the entire nested object in the update method.
|
||||
|
||||
For example, consider that you have a `details` object within the `metadata`:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "brand_123",
|
||||
"metadata": {
|
||||
"category": "electronics",
|
||||
"details": {
|
||||
"warranty": "1 year",
|
||||
"origin": "China"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
To update the `warranty` property within the `details` object, you need to provide the entire `details` object in the update method:
|
||||
|
||||
```ts
|
||||
const brand = await brandModuleService.updateBrands({
|
||||
id: "brand_123",
|
||||
metadata: {
|
||||
details: {
|
||||
warranty: "2 years",
|
||||
origin: "China"
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
The brand record will now have the `metadata` property updated with the new `warranty` value:
|
||||
|
||||
```json title="Result"
|
||||
{
|
||||
"id": "brand_123",
|
||||
"metadata": {
|
||||
"category": "electronics",
|
||||
"details": {
|
||||
"warranty": "2 years",
|
||||
"origin": "China"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Remove a Property from the JSON Property
|
||||
|
||||
To remove a property from the JSON property, you can pass an empty string as the value of the property in the update method.
|
||||
|
||||
For example, to remove the `is_featured` property from the `metadata`:
|
||||
|
||||
```ts
|
||||
const brand = await brandModuleService.updateBrands({
|
||||
id: "brand_123",
|
||||
metadata: {
|
||||
is_featured: "",
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
The brand record will now have the `metadata` property updated to remove the `is_featured` property:
|
||||
|
||||
```json title="Result"
|
||||
{
|
||||
"id": "brand_123",
|
||||
"metadata": {
|
||||
"category": "home appliances"
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -220,7 +220,7 @@ export default Post
|
||||
|
||||
### json
|
||||
|
||||
The `json` method defines a property whose value is a stringified JSON object.
|
||||
The `json` method defines a property whose value is stored as a stringified JSON object in the database.
|
||||
|
||||
For example:
|
||||
|
||||
@@ -237,6 +237,8 @@ const Post = model.define("post", {
|
||||
export default Post
|
||||
```
|
||||
|
||||
Learn more in the [JSON Properties](../json-properties/page.mdx) chapter.
|
||||
|
||||
### array
|
||||
|
||||
The `array` method defines an array of strings property.
|
||||
|
||||
Reference in New Issue
Block a user