Guide: Query Product's Brands

In the previous chapters, you defined a link between the custom Brand Module and MedusaGo's Product Module, then extended the create-product flow to link a product to a brand.

In this chapter, you'll learn how to retrieve a product's brand (and vice-versa) in two ways: Using MedusaGo's existing API route, or in customizations, such as a custom API route.


Approach 1: Retrieve Brands in Existing API Routes#

MedusaGo's existing API routes accept a fields query parameter that allows you to specify the fields and relations of a model to retrieve. So, when you send a request to the List Products, Get Product, or any product-related admin routes that accept a fields query parameter, you can specify in this parameter to return the product's brands.

For example, send the following request to retrieve the list of products with their brands:

Code
curl 'http://localhost:9000/admin/products?fields=+brand.*' \
-H 'Authorization: Bearer {token}'
Tip: Make sure to replace {token} with your admin user's authentication token. Learn how to retrieve it in the API reference.

Any product that is linked to a brand will have a brand property in its object:

Example Product Object
{
  "id": "prod_123",
  // ...
  "brand": {
    "id": "01JEB44M61BRM3ARM2RRMK7GJF",
    "name": "Acme",
    "created_at": "2024-12-05T09:59:08.737Z",
    "updated_at": "2024-12-05T09:59:08.737Z",
    "deleted_at": null
  }
}

By using the fields query parameter, you don't have to re-create existing API routes to get custom data models that you linked to core data models.

Note: Store API routes only return the fields and relations they allow. To retrieve your linked data models from a store route, allow them in the route's configuration, as explained in the Allowed Fields chapter.

Limitations: Filtering by Brands in Existing API Routes#

While you can retrieve linked records using the fields query parameter of an existing API route, you can't filter by linked records.

Instead, you'll have to create a custom API route that uses Query to filter by linked records.


Approach 2: Use Query to Retrieve Linked Records#

You can also retrieve linked records using Query. Query allows you to retrieve data across modules with filters, pagination, and more. You can resolve Query from the container and use it in your API route or workflow.

For example, you can create an API route that retrieves brands and their products. If you followed the Create Brands API route chapter, you'll have the file src/api/admin/brands/route.go with a POST API route. Add a new GET function to the same file:

src/api/admin/brands/route.go
// GET lists the brands with their linked products.
func GET(req *medusahttp.MedusaRequest, res *medusahttp.MedusaResponse) error {
	q := httputils.QueryOf(req.Scope)

	result, err := q.Graph(req.Ctx(), query.GraphInput{
		Entity: "brand",
		Fields: []string{"*", "products.*"},
	}, joiner.Options{})
	if err != nil {
		return err
	}

	out := dal.NewRecord()
	out.Set("brands", result.Data)
	return res.JSON(out)
}

This adds a GET API route at /admin/brands. In the API route, you resolve Query from the container with QueryOf, from the http/utils package of the Framework (github.com/hitkey-io/medusago/packages/core/framework/src/http/utils, imported with the alias httputils). Query has a Graph method that runs a query to retrieve data. It accepts a context, a query.GraphInput value, and options. The input has the following properties:

  • Entity: The data model's name as specified in the first parameter of dml.Define.
  • Fields: A list of properties and relations to retrieve. You can pass:
    • A property's name, such as id, or * for all properties.
    • A relation or linked model's name, such as products (use the plural name since brands are linked to list of products). You suffix the name with .* to retrieve all its properties.

Graph returns a result whose Data property is the list of retrieved brands. You return the brands in the response.

Then, update the Route variable in the same file to list both handlers, and make sure the route file is registered in src/api/routes.go, as you did in the API route chapter:

src/api/admin/brands/route.go
// Route holds the handlers of the route file. Its path is set where the
// route is registered, in src/api/routes.go.
var Route = medusahttp.Route{GET: GET, POST: POST}
Note: Learn more about Query in the Query chapter.

Test it Out#

To test the API route out, send a GET request to /admin/brands:

Code
curl 'http://localhost:9000/admin/brands' \
-H 'Authorization: Bearer {token}'
Tip: Make sure to replace {token} with your admin user's authentication token. Learn how to retrieve it in the API reference.

This returns the brands in your store with their linked products. For example:

Example Response
{
  "brands": [
    {
      "id": "123",
      // ...
      "products": [
        {
          "id": "prod_123",
          // ...
        }
      ]
    }
  ]
}

Filter by Brand in Query#

You can also filter products by their linked brand, with a filter on the brand relation. For example:

src/api/admin/brands/filter.go
// ProductsOfBrand retrieves the products linked to a brand with the given
// name, with their brand.
func ProductsOfBrand(ctx context.Context, scope medusahttp.MedusaContainer, name string) ([]any, error) {
	brandFilter := dal.NewRecord()
	brandFilter.Set("name", name)
	filters := dal.NewRecord()
	filters.Set("brand", brandFilter)

	result, err := httputils.QueryOf(scope).Graph(ctx, query.GraphInput{
		Entity:  "product",
		Fields:  []string{"*", "brand.*"},
		Filters: filters,
	}, joiner.Options{})
	if err != nil {
		return nil, err
	}
	return result.Data, nil
}

This retrieves only the products linked to a brand with the given name. Learn more about filtering by linked records in the Query chapter.


Summary#

By following the examples of the previous chapters, you:

  • Defined a link between the Brand and Product modules' data models, allowing you to associate a product with a brand.
  • Extended the create-product workflow and route to allow setting the product's brand while creating the product.
  • Queried a product's brand, and vice versa.

Next Steps: Customize Medusa Admin#

Client applications, such as the Medusa Admin dashboard, can now use brand-related features, such as creating a brand or setting the brand of a product.

In the next chapters, you'll learn how to customize the Medusa Admin to show a product's brand on its details page, and to show a new page with the list of brands in your store. Continue with the Customize Medusa Admin chapter.

Found a problem with this page?Report Issue
Edited Nov 14·Edit this page