Appearance
Rest handler
Handles one REST operation (method + route) behind an Http listener: it accepts only matching requests, extracts route, query and body parameters into a typed record and emits it. Connect several Rest handlers to the same listener Output pin, one per operation; each request goes to the handler(s) whose route matches. It also serves an OpenAPI (swagger.json) document for all Rest handlers of the flow.
Pins
| Pin | Kind | Types | Description |
|---|---|---|---|
| Input | input | Viaducta.Plugins.Http.Types.WebHttpRequest | Request from the Http listener Output pin. |
| Output | output | generated (see Behaviour) | Parameters of the call as a typed record. |
| Validate | validate | Viaducta.Plugins.RestApiListener.RestRequest | Called before the output with the parsed route (HttpRequest, HostName, Port, BaseUrl, BaseUrlParts, HttpMethod, MethodName, QueryString, RouteParameterValues). An error rejects the request. |
Configuration
| Field | Type | Default | Description |
|---|---|---|---|
Route | route builder | Required. Display form of the route, e.g. /api/GetOrder/{id}. Regenerated from RouteSpecification (reconfigures the component). | |
TypeName | string | Name of the generated output type. Empty: <name>Request. Changing it reconfigures the component. | |
RouteSpecification | hidden string (JSON) | The actual definition, written by the route builder dialog. |
RouteSpecification format
json
{
"service": "Orders",
"baseUrl": "/api",
"name": "GetOrder",
"httpMethod": "GET",
"parameters": [
{ "name": "id", "position": 2, "type": "System.Int32" },
{ "name": "details", "position": 3, "type": "System.Boolean", "defaultValue": "false" }
],
"returnTypeContainer": "Instance",
"returnType": ""
}httpMethod: upper caseGET,POST,PUT,PATCH,DELETE,HEAD,OPTIONS.position:1FromBody,2FromRoute,3FromQuery.type: .NET full type name (System.String,System.Int32, ...) or the full name of a flow type.service(OpenAPI tag),returnTypeContainer(Instance,List,Dictionary) andreturnTypeare only used for the OpenAPI document.- After editing the JSON by hand, the
Routefield must be reconfigured to regenerate the output type.
Behaviour
- Route template:
<baseUrl>/<name>/{routeParam1}/{routeParam2}.... A request matches when the method is equal (ignoring case) and its full path has the same number of segments (empty segments are skipped), fixed segments equal (case-insensitive) and route parameter segments filled. SobaseUrlmust contain the listener path: listenerhttp://0.0.0.0:9000/api+baseUrl/api+nameGetOrder→GET /api/GetOrder/42. Query parameters don't take part in matching. The route is compiled once when the flow starts. - Output type: no parameters →
Viaducta.TypeSystem.Metadata.NoInputData; a single FromBody parameter whose type is a flow type → that type; otherwise a generated class (TypeName) in the flow namespace with one property per parameter. Saving the route or changingTypeNamerebuilds it and removes the type generated before. - Values: the body JSON (
Body, orByteBodyas UTF-8 when the listener keeps the raw body) is read as the output type; an empty body leaves the defaults. Then route and query values are written over it, so a route or query value always wins over the same property in the body. FromRoute - the segment, unescaped on its own (%2Fstays inside the value,+stays+), converted to the property type. FromQuery - the first value (name exact, else ignoring case) converted; missing (or empty for non-text types) → the parameter'sdefaultValue, elsenullfor nullable types, else 400. - Validate pin: gets the
RestRequestafter the route matched, soRouteParameterValuesholds the route values; an error there stops the request. - A request that can't be read - body that is not JSON of the output type, a route or query value of the wrong type, a missing required query parameter - is answered
400with the listener's JSON error (code400) and nothing is emitted. - A
GETwhose last path segment isswagger.jsonis answered with an OpenAPI 3.1 document (JSON) of all Rest handlers in the flow; only one Rest handler per request answers it (the first one the listener asks). Paths carry the route placeholders (/api/GetOrder/{id}); route parameters are required, query parameters are optional when they have adefaultValueor a nullable type; the body is the parameter's flow type when it is the only parameter, else an object<Name>Bodywith one property per body parameter; the answer isreturnType(List= array,Dictionary= object);400and500carry the listener's JSON error (ViaductaError). The server is the request's scheme and host, orX-Forwarded-Proto/X-Forwarded-Host/X-Forwarded-Prefixwhen a proxy sends them. The document is written by Viaducta.CodeGen (OpenApiWriter.ForRestApi) and cached per server. - No
Outputconnection: nothing is emitted and the listener returns500(no response sent).
Notes
- With the generated class, the FromBody JSON must contain the properties of that class (one property per parameter), not the bare body object.
- Errors in the flow after the Rest handler are returned by the listener as
500JSON errors. - When no Rest handler matches, nothing handles the request and the listener answers
500"The response ... was never sent". - Two Rest handlers with the same method and route shape are both called; the OpenAPI document lists the first one and names the other in
x-viaducta-contract.warnings.
Example
Http listener (http://0.0.0.0:9000/api) → Rest handler (GET /api/GetOrder/{id}) → Database reader → Json serializer → Http response