Named Params
Capture route segments by name with :name, or capture and coerce to a typed value with :name=type. Captured values are available on req.params.
Basic syntax
Prefix a segment with : to name it. The value is always a string unless a type annotation is added.
-- :id captures any single segment as a string
app:Get("player/:id", function(req, res)
print(req.params.id) -- "123" (string)
end)
-- :id=number coerces to a number
app:Get("player/:id=number", function(req, res)
print(req.params.id) -- 123 (number)
end)
Supported types
| Annotation | Input | Result type |
|---|---|---|
:name | Any segment | string |
:name=number | Numeric string | number |
:name=int | Integer string (no decimal) | number |
:name=boolean | "true" or "false" | boolean |
:name=vector2 | Vector2-shaped segment | Vector2 |
:name=vector3 | Vector3-shaped segment | Vector3 |
:name=cframe | CFrame-shaped segment | CFrame |
:name=color3 | Color3-shaped segment | Color3 |
:name=Enum | Any EnumItem (wire format carries the type) | EnumItem |
:name=Enum.CameraType | Specific Enum type | EnumItem |
:name=instance | Instance reference | Instance |
Examples
-- Integer item ID
app:Get("shop/:itemId=int", function(req, res)
print(req.params.itemId) -- always a whole number
end)
-- Boolean flag
app:Get("flag/:on=boolean", function(req, res)
print(req.params.on) -- true or false
end)
-- Vector3 position
app:Get("pos/:v=vector3", function(req, res)
print(req.params.v) -- Vector3 value
end)
-- Specific Enum type
app:Get("cam/:mode=Enum.CameraType", function(req, res)
print(req.params.mode) -- EnumItem
end)
Coercion failure and OnParamError
When a typed param fails coercion (wrong format or out of range), the default behaviour is to respond 400 automatically and skip the handler. Override this with app:OnParamError(fn).
app:OnParamError(function(req, res, paramName, value)
res:Status(422):Send({ error = "Bad param: " .. paramName })
end)
:id(%d+)=number. See Constraints for the full syntax.RouteBuilder — typed URL construction
Router.Route(pattern) pairs a pattern with a type-checked URL builder so your handler registration and URL construction can never drift apart.
local GetCoins = RoExpress.Router.Route("player/:UserId=number/coins") :: RoExpress.RouteBuilder<{
UserId: number,
}>
App:Get(GetCoins.pattern, function(req, res)
res:Send({ coins = 100 })
end)
-- .build() is type-checked and always serialises correctly
GetCoins.build({ UserId = 12345 }) -- "/player/12345/coins"
See also
← Router · Constraints | Lua pattern restrictions on param values · Wildcards & Globs | unnamed captures · App | OnParamError handler · Exported Types | RouteBuilder<T>