API Route Parameters

In this chapter, you'll learn about path, query, and request body parameters.

Path Parameters#

To create an API route that accepts a path parameter, add a path segment of the format :param to the route file's Path.

For example, to create an API route at the path /hello-world/:id, where :id is a path parameter, create the route file with the following handler:

src/api/hello-world/id/route.go
func helloByID(req *medusahttp.MedusaRequest, res *medusahttp.MedusaResponse) error {
	return res.JSON(map[string]any{
		"message": fmt.Sprintf("[GET] Hello %s!", req.Params["id"]),
	})
}

The MedusaRequest object has a Params property. Params holds the path parameters in key-value pairs, as a map[string]string. The values are URL-decoded.

Multiple Path Parameters#

To create an API route that accepts multiple path parameters, add multiple segments of the format :param to the Path.

For example, to create an API route at /hello-world/:id/name/:name, use the following handler:

src/api/hello-world/id/name/route.go
func helloByIDAndName(req *medusahttp.MedusaRequest, res *medusahttp.MedusaResponse) error {
	return res.JSON(map[string]any{
		"message": fmt.Sprintf("[GET] Hello %s - %s!", req.Params["id"], req.Params["name"]),
	})
}

You access the id and name path parameters using the req.Params property.

Register the Routes#

The route files for these handlers set the paths with the path parameters:

src/api/parameters.go
// ParameterRoutes are the route files of the parameters chapter.
var ParameterRoutes = []medusahttp.RouteFile{
	{Path: "/hello-world/:id", Route: medusahttp.Route{GET: helloByID}},
	{Path: "/hello-world/:id/name/:name", Route: medusahttp.Route{GET: helloByIDAndName}},
	{Path: "/greeting", Route: medusahttp.Route{GET: greetGET, POST: greetPOST}},
}

Query Parameters#

You can access all query parameters in the Query property of the MedusaRequest object. Query is an ordered object of type *dal.Record, whose keys are the query parameters' names.

Use the Get method of Query to retrieve a parameter. It returns the value and a boolean that indicates whether the parameter exists. The query string is parsed like Express parses it with the qs library, so the value of a parameter is:

  • A string, if the parameter is passed once, such as ?name=John.
  • A []any of strings, if it's passed multiple times or with brackets, such as ?id[]=1&id[]=2.
  • A *dal.Record, if it's an object, such as ?created_at[$gt]=2026-01-01.

For example:

src/api/greeting/route.go
func greetGET(req *medusahttp.MedusaRequest, res *medusahttp.MedusaResponse) error {
	name, _ := queryString(req.Query, "name")

	return res.JSON(map[string]any{
		"message": fmt.Sprintf("Hello %s", name),
	})
}

The value of the name variable is the value passed in ?name=John, for example.

The queryString function in this example is a small helper that returns the value of a parameter if it's a string:

src/api/helpers.go
// queryString returns a query parameter when it is a single string.
func queryString(q *dal.Record, key string) (string, bool) {
	if q == nil {
		return "", false
	}
	v, ok := q.Get(key)
	if !ok {
		return "", false
	}
	s, ok := v.(string)
	return s, ok
}

Validate Query Parameters#

You can apply validation rules on received query parameters to ensure they match specified rules and types.

Learn more in the API Route Validation chapter.


Request Body Parameters#

The MedusaGo application parses the body of any request with a JSON, URL-encoded, or text content type. The request body is set in the MedusaRequest's Body property, whose type depends on the content type:

Content Type

Type of Body

application/json

A *dal.Record for a JSON object, or a []any for a JSON array.

application/x-www-form-urlencoded

A *dal.Record.

text/plain

A string.

If the request has no body, or has another content type, Body is an empty *dal.Record. In JSON bodies, numbers are float64 values, like in JavaScript.

Tip: Learn more about configuring body parsing, such as the size limit, in the Middlewares chapter.

For example:

src/api/greeting/route.go
func greetPOST(req *medusahttp.MedusaRequest, res *medusahttp.MedusaResponse) error {
	value, _ := body(req.Body).Get("name")
	name, _ := value.(string)

	return res.JSON(map[string]any{
		"message": fmt.Sprintf("[POST] Hello %s!", name),
	})
}

In this example, you use the name request body parameter to create the message in the returned response. The body function is a helper that converts req.Body into a *dal.Record, or an empty one if it isn't an object:

src/api/helpers.go
// body returns the parsed request body as an object (empty when the request
// has no JSON object body).
func body(raw any) *dal.Record {
	if r, ok := raw.(*dal.Record); ok && r != nil {
		return r
	}
	return dal.NewRecord()
}

To test it out, send the following request to your MedusaGo application:

Code
curl -X POST 'http://localhost:9000/greeting' \
-H 'Content-Type: application/json' \
--data-raw '{
  "name": "John"
}'

This returns the following JSON object:

Code
{
  "message": "[POST] Hello John!"
}

Validate Body Parameters#

You can apply validation rules on received body parameters to ensure they match specified rules and types.

Learn more in the Body Validation chapter.

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