F# code generation Phase C (partial): static-response HTTP endpoints (GH-2969)#2976
Merged
jeremydmiller merged 1 commit intoMay 29, 2026
Conversation
…H-2969) Phase C of the F# code-generation audit (#2969) — Wolverine.Http. Stands up the HTTP F# fixture surface and renders a real HttpChain to compilable F# for the static-response (GET) path. - New per-surface trio under src/Testing/: Wolverine.Http.FSharpContracts (endpoint classes), Wolverine.Http.FSharpFixture (F#, checked-in Generated.fs), Wolverine.Http.FSharpTests (compile gate + HTTP fsharp-coverage smoke test). Added to wolverine_fsharp.slnx; CI now runs `dotnet test wolverine_fsharp.slnx` across both the Core and Http surfaces. - HTTP chains render with no web host via HttpChain.ChainFor<T>(x => x.Method(), httpGraph) + httpGraph.StartAssembly(rules) + AssembleTypes + GenerateFSharpCode. The generated type subclasses the public HttpHandler base. - WriteStringFrame emits F# (HttpHandler.WriteString is static, so it resolves without a `this`). A `[WolverineGet]` endpoint returning a string renders and compiles end to end. Deferred — blocked on the JasperFx F# self-identifier gap (to be filed upstream): HttpHandler.ReadJsonAsync<T> and WriteJsonAsync<T> are INSTANCE methods called unqualified in the generated handler, which F# cannot resolve from a `member _.Handle` body. So ReadJsonBody / WriteJsonFrame (the JSON POST path) can't emit F# until JasperFx emits a named self for generated members. The POST endpoint is kept in the contracts for that follow-up but is not rendered yet. Same root gap as RecordMessageCausationFrame (Phase B). fsharp-coverage with Wolverine.Http loaded: 25 implemented / 2 skipped / 54 remaining of 81 Frame types. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This was referenced Jun 1, 2026
Merged
This was referenced Jun 4, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Phase C of the F# code-generation audit (#2969) — Wolverine.Http. Stands up the HTTP F# fixture surface and renders a real
HttpChainto compilable F# for the static-response (GET) path.What's here
src/Testing/:Wolverine.Http.FSharpContracts(endpoint classes),Wolverine.Http.FSharpFixture(F#, checked-inGenerated.fs),Wolverine.Http.FSharpTests(compile gate + HTTPfsharp-coveragesmoke test). Added towolverine_fsharp.slnx; CI now runsdotnet test wolverine_fsharp.slnxacross both the Core and Http surfaces.HttpChain.ChainFor<T>(x => x.Method(), httpGraph)→httpGraph.StartAssembly(rules)→AssembleTypes→GenerateFSharpCode(new ServiceCollectionServerVariableSource(container)). The generated type subclasses the publicHttpHandlerbase (override _.Handle(httpContext) : Task).WriteStringFrameemits F# —HttpHandler.WriteStringis static, so it resolves without athis. A[WolverineGet]string endpoint renders and compiles end to end.Generated F#
Deferred — blocked on a JasperFx-layer gap (to be filed upstream)
HttpHandler.ReadJsonAsync<T>andWriteJsonAsync<T>are instance methods called unqualified in the generated handler. F# can't resolve them from amember _.Handlebody (no self identifier), soReadJsonBody/WriteJsonFrame— the whole JSON POST path — can't emit F# until JasperFx emits a named self for generated members (e.g.member this.Handle+ frames emitthis.WriteJsonAsync). This is the same root gap asRecordMessageCausationFrame(Phase B) and is the single biggest lever for HTTP coverage. The POST endpoint is kept in the contracts for that follow-up but isn't rendered yet.Verification
Generated.fs(GET endpoint) compiles viadotnet build.fsharp-coveragewithWolverine.Httploaded — 25 implemented / 2 skipped / 54 remaining of 81.dotnet build wolverine_fsharp.slnx -c Release+ all 4 gate/coverage tests — green.dotnet build wolverine.slnx -c Releaseregression — 0 warnings, 0 errors.Part of #2969.
🤖 Generated with Claude Code