Skip to content

#2742: extract WolverineFx.Http.Newtonsoft package#2807

Merged
jeremydmiller merged 1 commit into
mainfrom
feature/2742-wolverine-http-newtonsoft-extraction
May 14, 2026
Merged

#2742: extract WolverineFx.Http.Newtonsoft package#2807
jeremydmiller merged 1 commit into
mainfrom
feature/2742-wolverine-http-newtonsoft-extraction

Conversation

@jeremydmiller

Copy link
Copy Markdown
Member

Wolverine 6.0 breaking change. Removes the Newtonsoft.Json dependency from the core WolverineFx.Http NuGet package and moves the Newtonsoft HTTP surface to a new WolverineFx.Http.Newtonsoft companion package — direct mirror of #2743 (which did the same extraction for the core WolverineFx package).

Closes #2742.

What moves

5.x API 6.0 location
WolverineHttpOptions.UseNewtonsoftJsonForSerialization(...) extension method in WolverineFx.Http.Newtonsoft
Wolverine.Http.NewtonsoftHttpSerialization Wolverine.Http.Newtonsoft.NewtonsoftHttpSerialization
ReadJsonBodyWithNewtonsoft codegen frame Wolverine.Http.Newtonsoft.CodeGen (internal)

Migrate by:

  1. dotnet add package WolverineFx.Http.Newtonsoft
  2. Add builder.Services.AddWolverineHttpNewtonsoft(); alongside AddWolverineHttp();
  3. Add using Wolverine.Http.Newtonsoft; wherever the old APIs are called
  4. The call signature of UseNewtonsoftJsonForSerialization itself doesn't change

What stays in core Wolverine.Http

  • The JsonUsage enum, including JsonUsage.NewtonsoftJson. Per the issue's open question Replace project icon and website in Directory.Build.props #1, the enum stays public on core; selecting NewtonsoftJson without the extension package installed throws an InvalidOperationException at codegen time pointing the user at dotnet add package WolverineFx.Http.Newtonsoft.
  • The codegen branches in JsonResourceWriterPolicy / JsonBodyParameterStrategy that dispatch on JsonUsage. They route through a new internal INewtonsoftHttpCodeGen seam when JsonUsage.NewtonsoftJson is selected; the seam is implemented in the extension package.

Branch points / decisions not pre-dictated by #2743

#2743 was an entirely-internal extraction (no public enum referenced the moved types). #2742 had to deal with JsonUsage.NewtonsoftJson being a public enum value on core that codegen branches on. Decisions made in this PR:

  1. Service registration is explicit, not transitive. Wolverine 5.x's AddWolverineHttp() registered NewtonsoftHttpSerialization unconditionally as a singleton — an over-allocation paid by every app whether it used Newtonsoft or not. This PR removes that registration from core and ships an AddWolverineHttpNewtonsoft() extension on IServiceCollection in the new package. Users opting in now make two calls (AddWolverineHttp().AddWolverineHttpNewtonsoft()) instead of one — explicit and pay-for-play.
  2. Settings flow through an internal object? slot. UseNewtonsoftJsonForSerialization is called inside MapWolverineEndpoints (after the DI container is built), so the user's Action<JsonSerializerSettings> callback can't be passed to the singleton at construction time directly. The extension stashes the callback on a new WolverineHttpOptions.NewtonsoftSettingsConfiguration (typed as object? so core stays Newtonsoft-free), and the new package's singleton factory reads it back on first DI resolve.
  3. ProblemDetailsContinuationPolicy.WriteProblems switched from Newtonsoft to STJ. Symmetric to Wolverine 6.0: extract Newtonsoft.Json to WolverineFx.Newtonsoft package (BREAKING) #2743's Subscription.Scope swap (StringEnumConverterJsonStringEnumConverter). This is a diagnostic-only log-line dump of ProblemDetails; ProblemDetails round-trips cleanly through STJ. No observable output-format change.
  4. AOT. The new package mirrors the IsAotCompatible=true + suppressions pattern from WolverineFx.Newtonsoft (chunk AJ AOT chunk AJ: flip IsAotCompatible=true on Wolverine.Newtonsoft (#2746) #2801, merged). One namespace-scoped IL3050 suppression covering the codegen MakeGenericMethod path; same justification as the parallel STJ branch in core Wolverine.Http.

Transports / other extensions

No transport changes. Wolverine.Http.Marten / Wolverine.Http.FluentValidation build clean against the slimmer core. Tests in Wolverine.Http.Tests get an explicit ProjectReference to the new package and the one affected test (using_newtonsoft_for_serialization) gets its using directive updated; no test logic changes.

Test plan

  • WolverineFx.Http.Newtonsoft builds clean on net9.0 and net10.0 (0 warnings / 0 errors)
  • WolverineFx.Http builds clean on net9.0 and net10.0 with no Newtonsoft transitive dependency
  • Wolverine.Http.Marten, Wolverine.Http.FluentValidation build clean
  • CI matrix validates the whole tree (kicking off with this PR)
  • using_newtonsoft_for_serialization.end_to_end end-to-end test — blocked locally by pre-existing AOT errors in Wolverine.EntityFrameworkCore (the test project's transitive dep), unrelated to this PR; will fall out of CI

Documentation

  • docs/guide/http/json.md: replaced the inline Newtonsoft setup snippet with a "WolverineFx.Http.Newtonsoft" subsection that calls out the package install + AddWolverineHttpNewtonsoft() registration + using Wolverine.Http.Newtonsoft; directive
  • docs/guide/messages.md: cross-reference tip directing HTTP-serialization users to the HTTP-specific package
  • docs/guide/migration.md: 3 new at-a-glance table rows + a full "Wolverine.Http Newtonsoft moved to WolverineFx.Http.Newtonsoft package (BREAKING)" section mirroring the prose pattern from Wolverine 6.0: extract Newtonsoft.Json to WolverineFx.Newtonsoft package (BREAKING) #2743's section

Build wiring

  • wolverine.slnx: new Wolverine.Http.Newtonsoft project added to the /Http/ folder
  • build/build.cs nugetProjects: WolverineFx.Http.Newtonsoft added to the pack list so it ships alongside core
  • Wolverine.Http.csproj: PackageReference Newtonsoft.Json removed; replaced with a pointer comment + InternalsVisibleTo grant for Wolverine.Http.Newtonsoft (so the extension can call internal HttpGraph.UseNewtonsoftJson(INewtonsoftHttpCodeGen))

Closes #2742; closes the Newtonsoft-extraction conversation from #2743 with the HTTP-side follow-up.

🤖 Generated with Claude Code

Removes the Newtonsoft.Json dependency from the core WolverineFx.Http
NuGet package and moves the Newtonsoft HTTP surface to a new
WolverineFx.Http.Newtonsoft companion package. Direct mirror of the
core extraction in #2743 (WolverineFx -> WolverineFx.Newtonsoft).

Per the issue: JsonUsage.NewtonsoftJson enum value stays in core; the
extension package "registers" the codegen wiring at runtime via an
internal INewtonsoftHttpCodeGen seam, and core throws a useful
InvalidOperationException at codegen time if the enum is selected
without the extension package installed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jeremydmiller jeremydmiller merged commit a9ef1a1 into main May 14, 2026
18 of 22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Newtonsoft.Json extraction: Wolverine.Http follow-up

1 participant