4.6.11. Retrieve Custom Links from Medusa's API Route

In this chapter, you'll learn how to retrieve custom data models linked to existing Medusa data models from Medusa's API routes.

Why Retrieve Custom Linked Data Models?#

Often, you'll link custom data models to existing Medusa data models to implement custom features or expand on existing ones.

For example, to add brands for products, you can create a Brand data model in a Brand Module, then define a link to the Product Module's Product data model.

When you implement this customization, you might need to retrieve the brand of a product using the existing Get Product API Route. You can do this by passing the linked data model's name in the fields query parameter of the API route.


How to Retrieve Custom Linked Data Models Using fields?#

Most of Medusa's API routes accept a fields query parameter that allows you to specify the fields and relations to retrieve in the resource, such as a product.

For example, to retrieve the brand of a product, you can pass the brand field in the fields query parameter of the Get Product API Route:

Code
1curl 'http://localhost:9000/admin/products/{id}?fields=*brand' \2-H 'Authorization: Bearer {access_token}'

The fields query parameter accepts a comma-separated list of fields and relations to retrieve. To learn more about using the fields query parameter, refer to the API Reference.

By prefixing brand with an asterisk (*), you retrieve all the default fields of the product, including the brand field. If you don't include the * prefix, the response will only include the product's brand.


Override Allowed Fields and Relations of Medusa's API Routes#

Some of Medusa's API routes restrict the fields and relations you can retrieve, which means you can't pass your custom linked data models in the fields query parameter. Medusa makes this restriction to ensure the API routes are performant and secure.

Every Store API route sets this restriction. A route only accepts a requested field whose full path is in its allowed list, and a relation in that list doesn't grant access to the fields nested under it. Medusa silently strips every other field from the query.

Note: Learn more about restricting retrievable fields, including how to apply the same restriction to your custom API routes and the full list of restricted core routes, in the Allowed Fields in API Routes chapter.

For these routes, you need to override the allowed fields and relations to be retrieved. You can do this by applying a global middleware to those routes.

For example, to allow retrieving the brand of a product using the List Products Store API Route, create the file src/api/middlewares.ts with the following content:

Warning: Only add the specific paths that the client needs. A broad entry, such as a relation that pulls in a whole data model, or a sensitive relation like an order, a payment, or another customer, exposes that data to anyone who calls the route. Store API routes are public, so treat every path you add to allowed as data you're willing to publish.
src/api/middlewares.ts
1import {2  allowFields,3  defineMiddlewares,4} from "@medusajs/framework/http"5
6export default defineMiddlewares({7  routes: [8    {9      matcher: "/store/products",10      middlewares: [allowFields("brand")],11    },12  ],13})

In this example, you apply the allowFields middleware to the List Products Store API Route. The middleware adds brand to the fields and relations that the route already allows.

Note: allowFields is available since Medusa v2.21.0. In earlier versions, write the middleware yourself and push the fields to the request's allowed property, as explained in the Allowed Fields chapter.

Pass the plain field path, without a *, +, or .* prefix or suffix. To also retrieve a field nested under the link, such as brand.name, pass that full path too.

You can now retrieve the brand field using the fields query parameter of the List Products Store API Route:

Code
1curl 'http://localhost:9000/store/products?fields=*brand' \2-H 'x-publishable-api-key: {your_publishable_api_key}'

In this example, you retrieve the brand relation of each product using the fields query parameter.

Important: This approach only works using a global middleware. It doesn't work in a route middleware.

Disallowed Fields in API Routes#

An API route can also block specific field path segments as a hard security boundary, which strips them from the query even if they're in the allowed list.

Medusa's API routes don't set disallowed fields, so overriding a route's allowed fields is enough to retrieve your custom linked data model. Learn how to block a segment on your own API routes in the Disallowed Fields in API Routes chapter.

Was this chapter helpful?
Ask Bloom
For assistance in your development, use Claude Code Plugins or Medusa MCP server in Cursor, VSCode, etc...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