question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

RFC: Replace Newtonsoft with System.Text.Json

See original GitHub issue

Introduction

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:open
  • Created 5 months ago
  • Reactions:1
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
adamrodgercommented, May 24, 2023

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.

0reactions
adamrodgercommented, May 27, 2023

Ok, well your feedback is taken on board, thanks.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Migrate from Newtonsoft.Json to System.Text.Json - .NET
During deserialization, Newtonsoft.Json ignores comments in the JSON by default. The System.Text.Json default is to throw exceptions for ...
Read more >
Migrate from Newtonsoft.Json to System.Text.Json - .NET
Json only accepts property names and string values in double quotes because that format is required by the RFC 8259 specification and is...
Read more >
Change EF json converter from system.text. ...
I have a postgres table with a jsonb column. This jsonb column has an object with an enum in it. The db stores...
Read more >
A Brief Comparison Between Newtonsoft.Json and System. ...
Text.Json is a new JSON library for .NET with different design goals from its predecessor, Newtonsoft.Json. If you're already using Newtonsoft.
Read more >
Migrating C# from Newtonsoft.Json to System.Text. ...
Start by backing up the projects, removing the Newtonsoft.Json package reference from them, and replacing either or both of these two lines.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found