RFC: Replace Newtonsoft with System.Text.Json
See original GitHub issueIntroduction
This is a request for comments from the community about a proposal to replace Newtonsoft with System.Text.Json as the main supported JSON serialiser.
Background
PactNet 4.x and below use the Newtonsoft JSON serialiser to:
- Serialise matchers to the special internal format required by FFI
- Serialise dynamic request and response bodies for interactions
- Deserialise message interaction contents from the FFI during verification
- Serialise consumer version selectors when loading pacts from a broker during verification
However, PactNet is most likely to be used with ASP.Net Core going forwards, in which the default JSON serialiser is Microsoft’s own System.Text.Json package. This creates friction when working with PactNet because any custom serialisation options applied to request/response objects need to be reimplemented in Newtonsoft just to work with pact tests.
This reimplementation could be incorrect because the two libraries sometimes behave differently, and therefore the worst case scenario for PactNet could easily happen - the pact tests will all pass but the service fails in production usage at runtime.
Proposal
All references to Newtonsoft JSON serialiser will be removed for PactNet 5.x and replaced with references to the Microsoft JSON serialiser.
This will create some breaking API changes where we currently support user-supplied serialisation settings, but the proposal
is simply to swap like-for-like from Newtonsoft’s JsonSerializerSettings
to System.Text.Json.JsonSerializerOptions
.
This will create a minimal impact during migration whilst still allowing us to change serialiser.
Internally, PactNet will use System.Text.Json
to serialise matchers and dynamic request/response bodies supply by users,
and to deserialise message interaction requests from the FFI during message interaction verification. To the user these
are entirely transparent changes.
The library will continue to ship as netstandard2.0
instead of changing to a direct .Net version so that existing compatibility
is maintained. System.Text.Json
supports netstandard2.0
explicitly.
Caveats/Drawbacks
Version
There is an open question on exactly which version of STJ to reference. If we pick the current version then we may prevent people from upgrading if they’re on older version. If we pick an older version then which one?
Breaking Serialisation Changes
Any custom serialisation options applied to objects previously which were not being used may now start to be used, and so potential behavioural differences might happen post-upgrade. For example, given the class:
public class MyDto
{
public int Foo { get; init; }
[System.Text.Json.Serialization.JsonIgnore]
public string Bar { get; init; }
}
In PactNet 4.x the Bar
property would still be serialised, whereas following this change it would no longer be serialised.
This behaviour seems advantageous rather than problematic, as it also wouldn’t be serialised by the real API under real usage
and thus the pacts were technically using the wrong format.
However, there are situations where the behaviour of serialisation itself may have been altered which could potentially cause behavioural changes. It’s not felt the risk is high or that the consequence is severe in these situations though. The correct action to perform in that case would ensure that the pacts and API are as close as possible anyway.
Issue Analytics
- State:
- Created 5 months ago
- Reactions:1
- Comments:6 (3 by maintainers)
Top GitHub Comments
The default JSON serialiser shipped with ASP.Net Core is STJ instead of Newtonsoft, and the default OpenAPI library is Swashbuckle instead of NSwag.
If we choose not to go with those defaults I think we need a good rationale beyond the things we personally prefer.
Ok, well your feedback is taken on board, thanks.