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:
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:
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:
// 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
[]anyof 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:
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:
// 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 |
|---|---|
| A |
| A |
| A |
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.
For example:
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:
// 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:
curl -X POST 'http://localhost:9000/greeting' \
-H 'Content-Type: application/json' \
--data-raw '{
"name": "John"
}'
This returns the following JSON object:
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.