3.5.3. JSON Properties in Data Models

In this chapter, you'll learn how to use and manage JSON properties 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:

Code
1import { model } from "@medusajs/framework/utils"2
3const Brand = model.define("brand", {4  id: model.id().primaryKey(),5  name: model.text(),6  metadata: model.json(),7})

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.
  • 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:

Code
1{2  "category": "electronics",3  "views": 1500,4  "is_featured": true,5  "tags": ["new", "sale"],6  "details": {7    "warranty": "2 years",8    "origin": "USA"9  }10}

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 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. The module's service will extend MedusaService, which generates methods like updateBrands 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.

Prerequisite: 

The following examples assume you have a brandModuleService that is resolved from the Medusa container. For example:

Code
const brandModuleService = container.resolve(BRAND_MODULE)

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:

Code
1const brand = await brandModuleService.updateBrands({2  id: "brand_123",3  metadata: {4    category: "electronics",5  },6})

The brand record will now have the metadata property updated to include the new category property:

Result
1{2  "id": "brand_123",3  "metadata": {4    "category": "electronics"5  }6}

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:

Code
1const brand = await brandModuleService.updateBrands({2  id: "brand_123",3  metadata: {4    is_featured: true,5  },6})

The brand record will now have the metadata property updated to include both category and is_featured properties:

Result
1{2  "id": "brand_123",3  "metadata": {4    "category": "electronics",5    "is_featured": true6  }7}

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:

Code
1const brand = await brandModuleService.updateBrands({2  id: "brand_123",3  metadata: {4    category: "home appliances",5  },6})

The brand record will now have the metadata property updated to reflect the new category value, and existing properties will remain unchanged:

Result
1{2  "id": "brand_123",3  "metadata": {4    "category": "home appliances",5    "is_featured": true6  }7}

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:

Code
1{2  "id": "brand_123",3  "metadata": {4    "category": "electronics",5    "details": {6      "warranty": "1 year",7      "origin": "China"8    }9  }10}

To update the warranty property within the details object, you need to provide the entire details object in the update method:

Code
1const brand = await brandModuleService.updateBrands({2  id: "brand_123",3  metadata: {4    details: {5      warranty: "2 years",6      origin: "China",7    },8  },9})

The brand record will now have the metadata property updated with the new warranty value:

Result
1{2  "id": "brand_123",3  "metadata": {4    "category": "electronics",5    "details": {6      "warranty": "2 years",7      "origin": "China"8    }9  }10}

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:

Code
1const brand = await brandModuleService.updateBrands({2  id: "brand_123",3  metadata: {4    is_featured: "",5  },6})

The brand record will now have the metadata property updated to remove the is_featured property:

Result
1{2  "id": "brand_123",3  "metadata": {4    "category": "home appliances"5  }6}

Manage JSON Properties in API Routes#

The instructions above also apply when managing JSON properties in API routes, since they typically use a service's update method under the hood.

Refer to the API reference to learn more about managing JSON properties, such as metadata, in API routes.

Was this chapter helpful?
Ask Anything
FAQ
What is Medusa?
How can I create a module?
How can I create a data model?
How do I create a workflow?
How can I extend a data model in the Product Module?
Recipes
How do I build a marketplace with Medusa?
How do I build digital products with Medusa?
How do I build subscription-based purchases with Medusa?
What other recipes are available in the Medusa documentation?
Chat is cleared on refresh
Line break