|
Csilk 0.2.1
A lightweight, high-performance C HTTP web framework
|
Route group implementation — prefix nesting with inherited middleware. More...

Data Structures | |
| struct | csilk_group_t |
| Route group structure. More... | |
Macros | |
| #define | CSILK_GROUP_MW_INIT_CAP 4 |
| Route group — holds a URL prefix, middleware chain, and optional parent group for nesting. | |
Functions | |
| static char * | join_path (const char *p1, const char *p2) |
| Internal: join two URL path components with a single '/' separator. | |
| csilk_group_t * | csilk_group_new (csilk_router_t *router, const char *prefix) |
| Create a new root route group with the given URL prefix. | |
| csilk_group_t * | csilk_group_group (csilk_group_t *parent, const char *prefix) |
| Create a child subgroup nested under a parent group. | |
| void | csilk_group_use (csilk_group_t *group, csilk_handler_t handler) |
| Register a middleware handler that applies to all routes in this group. | |
| static int | gather_handlers (csilk_group_t *group, csilk_handler_t **handlers, size_t *count) |
| Internal: recursively collect all middleware handlers from a group and its ancestors into a flat array. | |
| void | csilk_group_add_route (csilk_group_t *group, const char *method, const char *path, csilk_handler_t handler) |
| Register a route on this group with a single handler. | |
| void | csilk_group_add_route_extended (csilk_group_t *group, const char *method, const char *path, csilk_handler_t handler, const char *input_type, const char *output_type, const char *summary, const char *description) |
| Register a route with OpenAPI metadata (input/output types, summary, description). | |
| void | csilk_group_add_route_extended_perm (csilk_group_t *group, const char *method, const char *path, csilk_handler_t handler, const char *input_type, const char *output_type, const char *summary, const char *description, const char *perm_required, const char *perm_resource) |
| Add a route with OpenAPI/reflection metadata to a group. | |
| void | csilk_group_add_handlers (csilk_group_t *group, const char *method, const char *path, csilk_handler_t *handlers, size_t count) |
| Register a route with a custom chain of handlers (middleware + route handler). | |
| void | csilk_group_free (csilk_group_t *group) |
| Free all resources associated with a route group. | |
Route group implementation — prefix nesting with inherited middleware.
Route groups let users attach middleware + route handlers under a common URL prefix. Groups form a tree: a root group (prefix "") has zero or more child subgroups, each with their own prefix segment.
When a route is registered on a group, the framework:
This means parent-group middleware runs before child-group middleware for every request matching that prefix.
Path components are joined via join_path(), which normalizes slashes: e.g., parent="/api", child="/v1" → "/api/v1".
| struct csilk_group_s |
Route group structure.

| Data Fields | ||
|---|---|---|
| size_t | middleware_capacity |
Allocated capacity (always ≥ count). |
| size_t | middleware_count |
Current number of middleware handlers. |
| csilk_handler_t * | middlewares |
Dynamically-grown array of middleware handlers for this group. Grown by doubling (initial cap = 4). Freed in csilk_group_free(). |
| csilk_group_t * | parent |
Parent group in the nesting tree, or NULL for root groups. Used by gather_handlers() to walk up the tree. Not owned. |
| char * | prefix |
URL prefix for routes in this group. Combined with parent prefix at creation via join_path(). Freed in csilk_group_free(). e.g., parent="/api", child="/v1" → "/api/v1". |
| csilk_router_t * | router |
Router where routes are registered. Inherited from parent or set explicitly in csilk_group_new(). Not owned by the group. |
| #define CSILK_GROUP_MW_INIT_CAP 4 |
Route group — holds a URL prefix, middleware chain, and optional parent group for nesting.
Groups form a tree via the parent pointer. The full middleware chain for any route is the concatenation of parent middleware (recursively) followed by this group's middleware, followed by the route handlers.
| void csilk_group_add_handlers | ( | csilk_group_t * | group, |
| const char * | method, | ||
| const char * | path, | ||
| csilk_handler_t * | handlers, | ||
| size_t | count | ||
| ) |
Register a route with a custom chain of handlers (middleware + route handler).
Add a route with an explicit array of handlers.
The final handler chain stored in the router looks like: [parent_mw..., group_mw..., handler_1, ..., handler_n]
| group | The route group. |
| method | HTTP method. |
| path | Path relative to the group prefix. |
| handlers | Array of handler functions (the chain). |
| count | Number of handlers in the array. |
| void csilk_group_add_route | ( | csilk_group_t * | group, |
| const char * | method, | ||
| const char * | path, | ||
| csilk_handler_t | handler | ||
| ) |
Register a route on this group with a single handler.
Add a route to the group.
The route's path is automatically prefixed with the group's prefix. The handler is wrapped in a 1-element array and passed to csilk_group_add_handlers() which combines group middleware.
| group | The route group. |
| method | HTTP method (e.g., "GET", "POST"). |
| path | Path relative to the group prefix (e.g., "/users"). |
| handler | The route handler function. |
| void csilk_group_add_route_extended | ( | csilk_group_t * | group, |
| const char * | method, | ||
| const char * | path, | ||
| csilk_handler_t | handler, | ||
| const char * | input_type, | ||
| const char * | output_type, | ||
| const char * | summary, | ||
| const char * | description | ||
| ) |
Register a route with OpenAPI metadata (input/output types, summary, description).
Add a route with OpenAPI/reflection metadata to a group.
Like csilk_group_add_route() but enriches the route with metadata used by the OpenAPI spec generator. The metadata is stored in the method handler for later retrieval by csilk_generate_openapi_json().
| group | The route group. |
| method | HTTP method. |
| path | Path relative to the group prefix. |
| handler | The route handler function. |
| input_type | Registered reflection type name for the request body (e.g., "CreateUserRequest"), or NULL. |
| output_type | Registered reflection type name for the response body, or NULL. |
| summary | Short description for OpenAPI operation summary. |
| description | Detailed description for OpenAPI operation. |
| void csilk_group_add_route_extended_perm | ( | csilk_group_t * | group, |
| const char * | method, | ||
| const char * | path, | ||
| csilk_handler_t | handler, | ||
| const char * | input_type, | ||
| const char * | output_type, | ||
| const char * | summary, | ||
| const char * | description, | ||
| const char * | perm_required, | ||
| const char * | perm_resource | ||
| ) |
Add a route with OpenAPI/reflection metadata to a group.
Add a route with full OpenAPI metadata and permission requirements to a group.
Extended version that also records input/output types and documentation for automatic OpenAPI spec generation.
| group | The route group. |
| method | HTTP method. |
| path | Path relative to the group prefix. |
| handler | The route handler function. |
| input_type | Registered type name for request-body binding (NULL if none). |
| output_type | Registered type name for response serialisation (NULL if none). |
| summary | Short operation summary for OpenAPI (NULL to omit). |
| description | Detailed operation description for OpenAPI (NULL to omit). |
Add a route with OpenAPI/reflection metadata to a group.
Like csilk_group_add_route() but enriches the route with metadata used by the OpenAPI spec generator. The metadata is stored in the method handler for later retrieval by csilk_generate_openapi_json().
| group | The route group. |
| method | HTTP method. |
| path | Path relative to the group prefix. |
| handler | The route handler function. |
| input_type | Registered reflection type name for the request body (e.g., "CreateUserRequest"), or NULL. |
| output_type | Registered reflection type name for the response body, or NULL. |
| summary | Short description for OpenAPI operation summary. |
| description | Detailed description for OpenAPI operation. |
| perm_required | Permission required for this route, or NULL. |
| perm_resource | Resource pattern for permission check, or NULL. |
Permission metadata is forwarded to the router which stores it alongside the route for authorization middleware to inspect at request time.
| void csilk_group_free | ( | csilk_group_t * | group | ) |
Free all resources associated with a route group.
Destroy a route group and release its resources.
Releases the group's prefix string, middleware handlers array, and the group struct itself. Does NOT free child groups or the router.
| group | The group to free (may be NULL). |
| csilk_group_t * csilk_group_group | ( | csilk_group_t * | parent, |
| const char * | prefix | ||
| ) |
Create a child subgroup nested under a parent group.
Create a nested sub-group within an existing group.
The child inherits the parent's router and its prefix is joined with the parent's prefix (e.g., parent="/api", child="/v1" -> combined prefix "/api/v1").
| parent | The parent group (cannot be NULL). |
| prefix | URL prefix for this subgroup (e.g., "/v1"). |
| csilk_group_t * csilk_group_new | ( | csilk_router_t * | router, |
| const char * | prefix | ||
| ) |
Create a new root route group with the given URL prefix.
Create a new route group with a URL prefix.
Root groups are attached directly to a router. All routes added to this group will be prefixed with prefix.
| router | The router instance this group belongs to. |
| prefix | URL prefix for all routes in this group (e.g., "/api/v1"). Pass NULL or "/" for no prefix. |
| void csilk_group_use | ( | csilk_group_t * | group, |
| csilk_handler_t | handler | ||
| ) |
Register a middleware handler that applies to all routes in this group.
Add middleware to a group.
Middleware handlers are executed before route handlers in the order they are registered. The internal middleware array grows dynamically (doubling capacity) as needed.
| group | The route group. |
| handler | Middleware handler function. Receives the request context and should call csilk_next() to pass control forward. |
|
static |
Internal: recursively collect all middleware handlers from a group and its ancestors into a flat array.
The recursion goes depth-first to the root, then appends middleware on the way back up:
gather_handlers(child, &arr, &n) → gather_handlers(parent, &arr, &n) // recurse to root first → gather_handlers(grandparent, &arr, &n) // root's parent is NULL → (no parent — return) → memcpy grandparent's middlewares into arr[n..] → n += grandparent.middleware_count → memcpy parent's middlewares into arr[n..] → n += parent.middleware_count → memcpy child's middlewares into arr[n..] → n += child.middleware_count
Result: [grandparent_mw..., parent_mw..., child_mw...] This guarantees parent middleware executes before child middleware.
| group | The leaf group. |
| handlers | [in/out] Pointer to the handlers array (realloc'd as needed). |
| count | [in/out] Number of handlers collected so far. |
|
static |
Internal: join two URL path components with a single '/' separator.
Examples: join_path("/api/", "/v1") → "/api/v1" join_path("api", "v1") → "api/v1" join_path(NULL, "/users") → "/users" join_path("", "") → "/"
| p1 | First path component (may be empty or NULL). |
| p2 | Second path component (may be empty or NULL). |