Properties
A Route instance contains the following information:
- URL: The path template for the endpoint (e.g.,
/api/v1/users/{id}).
- Method: An implementation of
MethodInterface representing the allowed HTTP verb (GET, POST, etc.).
- Description: An optional human-readable description used for documentation (OpenAPI).
- Tags: A collection of
TagObject instances used for grouping endpoints in documentation.
- Security Requirements: A
RouteAuthorization instance defining the authentication and authorization needed for the route.
- Rate Limit: An optional
RateLimitInterface implementation defining the rate limiting rules for the endpoint.
- Sorting: A collection of
Sort instances defining allowed sorting fields for the endpoint.
- Pagination: A
Pagination instance defining the pagination strategy (Page, Offset, or Cursor).
- Filtering: A collection of
FilterInterface instances defining allowed filtering fields for the endpoint.
- Path Properties: Typed
AbstractProperty instances defining each path parameter (e.g. {id}, {user_uuid}), declared via chained pathProperty() calls.
- Documentation Exclusion: A flag set via
excludeFromDocumentation() that keeps the route out of the generated OpenAPI spec.
Path Parameters
Routes support dynamic path parameters using the {parameterName} syntax. Parameter names may contain letters, digits, and underscores ([a-zA-Z0-9_]).
Define the type and description of each path parameter directly on the route using pathProperty():
This is the preferred way to declare path parameters. Defining them on the route means the type, validation, and OpenAPI documentation are all co-located with the URL pattern rather than split across a separate request class.
Path parameters defined via pathProperty() are automatically:
- Validated and type-cast when the request is populated
- Included in the OpenAPI spec as
in: path parameters
- Included in the generated path shape for IDE type hints
Validators
Any property constraint supported by Apivalk can be applied to a path parameter:
Constraints are serialized with the route when route caching is enabled and are fully restored on cache load.
Path parameters are always required
pathProperty() always enforces isRequired(true) regardless of what is set on the property. Path parameters are structurally required — the route only matches when they are present in the URL. Marking one optional would produce an invalid OpenAPI spec (required: false on a path parameter violates the OpenAPI specification).
Accessing path parameters
Backward compatibility
Path properties can also be declared in the request class via addPathProperty() in getDocumentation(). Both sources are merged — you can use either or both. pathProperty() on the route is preferred for new code.
Security and Authorization
Security requirements are defined on a per-route basis using the RouteAuthorization object. This allows you to specify which authentication scheme (e.g., Bearer, OAuth2) is required and what granular scopes and permissions the user must have.
Public Route
If no RouteAuthorization is provided (default), the route is fully public. Anyone can access it.
Authenticated Route (No Specific Scopes)
To require authentication without enforcing specific scopes or permissions, pass only the security scheme name. The SecurityMiddleware will reject anonymous users with a 401 Unauthorized but allow any authenticated identity through.
Scoped Route (Specific Scopes and Permissions)
To require both authentication and specific scopes/permissions:
Optional Security (Public with Identity)
If you want a route to be public but optionally use identity information when a token is provided, leave RouteAuthorization as null. The AuthenticationMiddleware will still populate the identity if a valid token is present, so you can check $request->getAuthIdentity()->isAuthenticated() in your controller.
For more details on how the security system works, check the Security Overview.
Integration with Documentation
The Route class implements JsonSerializable, allowing it to be easily exported for OpenAPI (Swagger) generation. It includes helper methods for:
jsonSerialize(): Converts the route and its metadata into a format suitable for JSON export.
static byJson(string $json): Hydrates a Route object from a JSON string, which is used when loading routes from the router cache.
Usage in Controllers
In an Apivalk application, you typically don’t instantiate Route objects manually. Instead, you define them in your controller’s static getRoute() method:
Rate Limiting
You can add rate limiting to a route by providing a rate limit object as the last argument to the Route constructor:
For more details on available rate limiting strategies, see the Rate Limit documentation.
Sorting
You can define which fields are allowed for sorting by using the sorting() method. This takes an array of Sort objects:
The sorting() method also defines the default sorting for the route. If a user does not provide an order_by query parameter, the sorting() bag on the request object will be automatically populated with these defined values.
You can enable pagination for a route using the pagination() method. This takes a Pagination object:
When pagination is enabled, the framework automatically handles the page, limit, offset, or cursor query parameters and includes them in the OpenAPI documentation. See the Pagination guide for more details.
Resource Routes
For CRUD endpoints against an AbstractResource, use Route::resource() to build a route pre-configured for one of the five resource modes. It derives the URL, HTTP method, and default configuration from the resource:
In practice you won’t call Route::resource() yourself — AbstractResourceController::getRoute() does it for you. See Resources.
Filtering
You can define which fields are allowed for filtering by using the filtering() method. This takes an array of FilterInterface instances:
One filter per field, with the operators that field accepts. Only configured fields are resolved from the request and documented in OpenAPI, and a field name that collides with order_by, offset, cursor, page or limit is rejected when the route is built. See the Filtering guide for more details.
QUERY Requests
enableQuery() makes a filtered route additionally reachable as an RFC 10008 QUERY request, where the filters arrive as a JSON body instead of a query string:
The route stays a GET route with the same controller; it is simply indexed under both methods. The generated spec gains a query operation whose requestBody mirrors the filter schemas.
It is opt-in because gateways that do not know the method drop such requests before they reach your application, and because SDK generators would otherwise emit two calls for the same read.
Excluding a Route from Documentation
Call excludeFromDocumentation() to keep an endpoint out of the generated OpenAPI spec. Useful for internal or private endpoints that should not show up in public API docs or generated SDKs.
This only affects documentation. Routing, authentication, authorization and rate limiting are untouched, the endpoint stays fully reachable at runtime. Protect internal endpoints with routeAuthorization(), not by hiding them from the spec.
The generator can opt back in via forceIncludeExcludedRoutes(), for an internal spec generated next to the public one. See OpenAPI Generator.