Skip to content

Parameter Routing & Path Segment Parsing

Introduction

Starting from v1.0.0.420, HttpServer introduces two important features:

  • Parameter Routing — Use {param} syntax in URL paths to define dynamic parameter segments, similar to modern frameworks like Laravel, Express, etc.
  • PathInfoList — Split URL paths by / into a collection object that supports access by index and by key

Used together, they make it easy to build RESTful-style APIs.


1. Parameter Routing

1.1 Basic Usage

When registering routes, use {paramName} to mark dynamic segments:

vb
' Single parameter route
Call Server.Router.Add("/api/user/{id}", "UserController@Show", OnlyGet)

' Multi-parameter route
Call Server.Router.Add("/api/user/{userId}/post/{postId}", "PostController@Show", OnlyGet)

' Nested resource route
Call Server.Router.Add("/api/group/{groupId}/user/{userId}", "GroupCtrl@Detail", OnlyGet)

1.2 Getting Parameters in Controllers

Access matched parameter values via the ctx.Request.RouteParams dictionary:

vb
' Single parameter example: GET /api/user/123
Public Sub Show(ctx As cHttpServerContext)
    Dim userId As String
    userId = ctx.Request.RouteParams("id")     ' Value is "123"

    ctx.Response.Json Array("userId" & userId)
End Sub

' Multi-parameter example: GET /api/user/456/post/789
Public Sub ShowPost(ctx As cHttpServerContext)
    Dim userId As String, postId As String
    userId = ctx.Request.RouteParams("userId") ' Value is "456"
    postId = ctx.Request.RouteParams("postId")  ' Value is "789"

    ctx.Response.Json Array(userId, postId)
End Sub

1.3 RouteParams Property

vb
Public RouteParams As New Scripting.Dictionary
OperationUsageDescription
Get parameterctx.Request.RouteParams("id")Returns parameter value string
Check existencectx.Request.RouteParams.Exists("id")Returns Boolean
Parameter countctx.Request.RouteParams.Count0 when no parameter route matched
Iterate parametersFor Each k In RouteParams.KeysIterate all parameter names

Note: If no parameter route is matched, RouteParams is an empty dictionary (Count = 0).

1.4 Matching Rules

RuleDescriptionExample
Parameter segment {name}Matches any non-empty string/api/user/{id} matches /api/user/123
Fixed segmentMust match exactly (case-insensitive)In /api/user/{id}, api and user are fixed segments
Same segment countPath segment count must match pattern segment count/api/user/{id} is 3 segments, won't match /api/user/123/edit (4 segments)
Parameter non-emptyParameter segment cannot match empty value/api/user/ does not match /api/user/{id}

Matching Examples:

Route PatternRequest PathMatch ResultRouteParams
/api/user/{id}/api/user/123{"id": "123"}
/api/user/{id}/api/user/abc{"id": "abc"}
/api/user/{id}/api/user/❌ Segment count mismatch
/api/user/{id}/api/users/123❌ Fixed segment mismatch
/api/user/{userId}/post/{postId}/api/user/456/post/789{"userId": "456", "postId": "789"}

1.5 Matching Priority

Route matching executes in the following priority order:

  1. Exact match — O(1) dictionary lookup, highest performance. e.g., /api/users matches directly
  2. ANY exact match — Look up in the ANY method dictionary
  3. Parameter route match — Traverse route items containing {param}, match segment by segment

Exact routes always take priority over parameter routes; parameter wildcard won't cause false matches.

vb
' Register both exact and parameter routes
Call Server.Router.Add("/api/user/me", "User@Me", OnlyGet)       ' Exact match first
Call Server.Router.Add("/api/user/{id}", "User@Show", OnlyGet)   ' Parameter route second

' GET /api/user/me   → Matches exact route, calls User@Me
' GET /api/user/123  → Matches parameter route, RouteParams("id") = "123"

1.6 Parameter Routing vs Query Parameters

ComparisonParameter RoutingQuery Parameters
URL format/api/user/123/api/user?id=123
Access methodctx.Request.RouteParams("id")ctx.Request.QueryString("id")
RESTful style✅ Conforms❌ Does not conform
SEO friendly✅ More friendlyAverage
Optional parametersSegment count must matchNaturally optional
Use caseResource identification, hierarchical pathsFiltering, pagination, sorting

Both can be combined:

vb
' GET /api/user/123/posts?page=2&limit=10
Call Server.Router.Add("/api/user/{id}/posts", "Post@List", OnlyGet)

Public Sub List(ctx As cHttpServerContext)
    Dim userId As String: userId = ctx.Request.RouteParams("id")
    Dim page As String: page = ctx.Request.QueryString("page")
    Dim limit As String: limit = ctx.Request.QueryString("limit")
End Sub

1.7 Complete RESTful API Example

vb
' Register controller
Call Server.Router.Reg("Product", New cProductController)

' List: GET /products
Call Server.Router.Add("/products", "Product@List", OnlyGet)

' Detail: GET /products/123
Call Server.Router.Add("/products/{id}", "Product@Detail", OnlyGet)

' Create: POST /products
Call Server.Router.Add("/products", "Product@Create", OnlyPost)

' Update: PUT /products/123
Call Server.Router.Add("/products/{id}", "Product@Update", OnlyPut)

' Delete: DELETE /products/123
Call Server.Router.Add("/products/{id}", "Product@Delete", OnlyDelete)

' Sub-resource: GET /products/123/reviews
Call Server.Router.Add("/products/{id}/reviews", "Product@Reviews", OnlyGet)

' Sub-resource detail: GET /products/123/reviews/456
Call Server.Router.Add("/products/{productId}/reviews/{reviewId}", "Product@ReviewDetail", OnlyGet)

1.8 Internal Implementation

Parameter routing is implemented by the cHttpServerRouteItem class, with the core mechanism:

  1. On registration: The Init method splits the route pattern into a path segment array and extracts {param} parameter names
  2. On matching: The Match method compares segment by segment — fixed segments match exactly (case-insensitive), parameter segments match any non-empty value
  3. Parameter extraction: After a successful match, parameter names and values are written to the Request.RouteParams dictionary
Route pattern: /api/user/{id}/post/{postId}
  ↓ Init() split
Segment array: ["api", "user", "{id}", "post", "{postId}"]
Parameter names: ["id", "postId"]

Request path: /api/user/123/post/456
  ↓ Match() segment-by-segment matching
"api"      = "api"    ✅ Fixed segment match
"user"     = "user"   ✅ Fixed segment match
"{id}"     = "123"    ✅ Parameter segment → RouteParams("id") = "123"
"post"     = "post"   ✅ Fixed segment match
"{postId}" = "456"    ✅ Parameter segment → RouteParams("postId") = "456"

2. PathInfoList Path Segment Collection

2.1 Introduction

PathInfoList is a cCollection type collection object that automatically splits the URL path by / during request parsing. Each segment is stored in the collection where both key and value are the segment name, supporting access by index and by key.

vb
Public PathInfoList As New cCollection

2.2 Usage Examples

vb
' Request: GET /api/user/list?page=1

' ── Access by index (1-based) ──
MsgBox ctx.Request.PathInfoList(1)     ' → "api"
MsgBox ctx.Request.PathInfoList(2)     ' → "user"
MsgBox ctx.Request.PathInfoList(3)     ' → "list"

' ── Get path segment count ──
MsgBox ctx.Request.PathInfoList.Count  ' → 3

' ── Access by key (key=value=segment name) ──
MsgBox ctx.Request.PathInfoList("api") ' → "api"

' ── Check if path contains a segment ──
If ctx.Request.PathInfoList.Exists("api") Then
    Debug.Print "Path contains 'api' segment"
End If

' ── Iterate all path segments ──
Dim i As Long
For i = 1 To ctx.Request.PathInfoList.Count
    Debug.Print "Segment" & i & ": " & ctx.Request.PathInfoList(i)
Next i

2.3 PathInfoList for Common Paths

Request PathPathInfoList.CountPathInfoList(1)PathInfoList(2)PathInfoList(3)
/0
/api1"api"
/api/user2"api""user"
/api/user/list3"api""user""list"
/api/user/1233"api""user""123"

2.4 Typical Use Cases

vb
' Check if it's an API request
If ctx.Request.PathInfoList.Count > 0 Then
    If ctx.Request.PathInfoList(1) = "api" Then
        ' Handle API request
    End If
End If

' Get resource ID from path (parameter routing is better for this)
If ctx.Request.PathInfoList.Count >= 3 Then
    If ctx.Request.PathInfoList(2) = "user" Then
        Dim userId As String
        userId = ctx.Request.PathInfoList(3)   ' e.g. "123"
    End If
End If

' Recommended: Use parameter routing to get IDs instead:
' userId = ctx.Request.RouteParams("id")

Tip: For getting dynamic parameters from the path (like user IDs), prefer using parameter routing's RouteParams — it's more semantic and type-safe.


3. New Files List

FileTypeDescription
cHttpServerRouteItem.clsNewRoute item class: parses {param} patterns, matches paths, extracts parameters
cHttpServerRouter.clsModifiedRoute matching logic: exact match first, parameter route second
cHttpServerRequest.clsModifiedAdded RouteParams (Dictionary) and PathInfoList (cCollection)

100% backward compatible — existing exact route registration and matching are not affected.


Last Updated: 2026-06-11

VB6 and LOGO copyright of Microsoft Corporation