Skip to content

OpenAPI: route ids bound only by a Marten aggregate frame render as 'string' instead of 'uuid' on unconstrained routes #3420

Description

@jeremydmiller

Follow-up from #3418 (the GH-3380 OpenAPI work), which fixed the general "derive parameters from the full binding chain" problem but explicitly does not close this one.

The shape

[AggregateHandler]
[WolverinePost("/orders/{id}/confirm")]
public static OrderConfirmed Handle(ConfirmOrder command, Order order) { ... }

The route has no constraint ({id}, not {id:guid}), and id appears nowhere in the handler's method signature — it's bound by the Marten aggregate frame, which resolves during codegen.

Result: the OpenAPI operation declares id as string rather than uuid.

Why #3418's fix doesn't reach it

#3418 resolves a route parameter's type as: route variable → binding chain → route constraint → string. For this shape all four rungs come up empty of type information — the binding happens inside a Marten-specific frame, and the id's real type (Guid, or a strongly-typed id) is Marten domain knowledge that Wolverine.Http cannot infer from method signatures. It correctly falls back to string.

Adding the constraint ({id:guid}) fixes it today, so there's a clean workaround, and the parameter is declared — it's the type that's wrong, not the presence. That's why this is a follow-up and not a blocker.

Direction

Wolverine.Http.Marten knows the aggregate's identity type. The fix probably belongs there — a seam letting the aggregate frame contribute its bound route parameter's CLR type back to the chain's ApiDescription, rather than Wolverine.Http trying to guess.

Now cheaply testable: the shape-test harness added in #3418 (src/Http/Wolverine.Http.Tests/openapi_shape_tests.cs) renders the real OpenAPI document without starting a host, so this is one endpoint plus one [Fact].

Refs #3380, #3418.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions