Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a System.Text.Json formatter #908

Merged
merged 35 commits into from
Apr 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
580d97f
Generalize the JSON tests that can be
AArnott Apr 18, 2023
a5f8362
Early System.Text.Json formatter work
AArnott Apr 18, 2023
6cefbab
Implement most of the message envelope serialization
AArnott Apr 18, 2023
6233833
Work on warnings
AArnott Apr 18, 2023
5f2f13a
Get most basic scenarios working
AArnott Apr 18, 2023
c754f1a
Use the user serializer for their own types
AArnott Apr 18, 2023
6a065a9
Support deserializing error data
AArnott Apr 18, 2023
4a4d726
More tests passing
AArnott Apr 18, 2023
db38a44
Add support for DataContractSerializer attributes
AArnott Apr 18, 2023
ed068f6
Consolidate shared formatter behavior in a new base class
AArnott Apr 19, 2023
603682b
Share more code across formatters
AArnott Apr 19, 2023
78d0eef
Share more state of incoming messages
AArnott Apr 19, 2023
47aeaff
Add support for `Progress<T>`
AArnott Apr 20, 2023
e01b2aa
Add support for `UseSingleObjectParameterDeserialization`
AArnott Apr 20, 2023
5c755a0
Share more tests across formatters
AArnott Apr 20, 2023
e55d170
Add top-level property support
AArnott Apr 20, 2023
1611b41
Share top-level property code across formatters
AArnott Apr 21, 2023
30619e9
Add callout for top-level and remote target support of alternative fo…
AArnott Apr 21, 2023
a1eac97
Fix outbound argument count
AArnott Apr 21, 2023
ae99ea2
Add exception serialization support
AArnott Apr 21, 2023
24be5be
Fix another test
AArnott Apr 21, 2023
81cb7b4
Add activity tracing support
AArnott Apr 21, 2023
b43abd6
Activate the rest of the exotic type tests
AArnott Apr 21, 2023
db84b57
Add support for OOB stream exotic types
AArnott Apr 24, 2023
955f837
Add `IAsyncEnumerable<T>` support
AArnott Apr 24, 2023
f4960ae
Add support for RPC general marshable objects
AArnott Apr 25, 2023
ab26715
Fix regression due to declared types
AArnott Apr 25, 2023
dee7465
Fix IFruitConverter test
AArnott Apr 25, 2023
3b3ddc6
Fix concurrency bug
AArnott Apr 25, 2023
e11290c
Fix the last of the failing tests
AArnott Apr 26, 2023
615fc2b
Document our support of System.Text.Json
AArnott Apr 26, 2023
628591e
Add support for tracing messages
AArnott Apr 26, 2023
51f5215
Remove unnecessary `partial` modifier on the new clas
AArnott Apr 26, 2023
961f81f
Recycle more memory
AArnott Apr 26, 2023
0f649cc
Applied PR feedback
AArnott Apr 28, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,5 @@
"files.trimFinalNewlines": true,
"omnisharp.enableEditorConfigSupport": true,
"omnisharp.enableImportCompletion": true,
"omnisharp.enableRoslynAnalyzers": true,
"dotnet.defaultSolution": "StreamJsonRpc.sln"
"omnisharp.enableRoslynAnalyzers": true
}
1 change: 1 addition & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
<PackageVersion Include="System.IO.Pipelines" Version="7.0.0" />
<PackageVersion Include="System.IO.Pipes" Version="4.3.0" />
<PackageVersion Include="System.Net.Http" Version="4.3.4" />
<PackageVersion Include="System.Text.Json" Version="7.0.2" />
AArnott marked this conversation as resolved.
Show resolved Hide resolved
<PackageVersion Include="System.Text.Encodings.Web" Version="7.0.0" />
<PackageVersion Include="System.Threading.Tasks.Dataflow" Version="7.0.0" />
<PackageVersion Include="System.ValueTuple" Version="4.5.0" />
Expand Down
33 changes: 30 additions & 3 deletions doc/extensibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,14 +88,24 @@ StreamJsonRpc includes the following `IJsonRpcMessageFormatter` implementations:
You can contribute your own via `MessagePackFormatter.SetOptions(MessagePackSerializationOptions)`.
See alternative formatters below.

1. `SystemTextJsonFormatter` - Uses the [`System.Text.Json` library][SystemTextJson] to serialize each
JSON-RPC message as UTF-8 encoded JSON.
All RPC method parameters and return types must be serializable by System.Text.Json,
with the additional benefit of `DataContract` and `DataMember` attributes being supported by default
matteo-prosperi marked this conversation as resolved.
Show resolved Hide resolved
within StreamJsonRpc where System.Text.Json alone does not support them.
You can leverage `JsonConverter<T>` and add your custom converters via attributes or by
contributing them to the `SystemTextJsonFormatter.JsonSerializerOptions.Converters` collection.

When authoring a custom `IJsonRpcMessageFormatter` implementation, consider supporting the [exotic types](exotic_types.md) that require formatter participation.
We have helper classes to make this straightforward.
Refer to the source code from our built-in formatters to see how to use these helper classes.

### Alternative formatters
### Choosing your formatter

#### When to use `MessagePackFormatter`

For performance reasons when both parties can agree, it may be appropriate to switch out the textual JSON
representation for something that can be serialized faster and/or in a more compact format.
The very best performance comes from using the `MessagePackFormatter` with the `LengthHeaderMessageHandler`.
This combination is the fastest and produces the most compact serialized format.

The [MessagePack format][MessagePackFormat] is a fast, binary serialization format that resembles the
structure of JSON. It can be used as a substitute for JSON when both parties agree on the protocol for
Expand All @@ -104,7 +114,24 @@ significant wins in terms of performance and payload size.
Utilizing `MessagePack` for exchanging JSON-RPC messages is incredibly easy.
Check out the `BasicJsonRpc` method in our [MessagePackFormatterTests][MessagePackUsage] class.

#### When to use `SystemTextJsonFormatter`

When the remote party does not support MessagePack but does support UTF-8 encoded JSON,
`SystemTextJsonFormatter` offers the most performant choice available.

This formatter is compatible with remote systems that use `JsonMessageFormatter`, provided they use the default UTF-8 encoding.
The remote party must also use the same message handler, such as `HeaderDelimitedMessageHandler`.

#### When to use `JsonMessageFormatter`

This formatter is the default for legacy reasons, and offers compatibility with data types that can only be serialized with Newtonsoft.Json.
It produces JSON text and allows configuring the text encoding, with UTF-8 being the default.
AArnott marked this conversation as resolved.
Show resolved Hide resolved

This formatter is compatible with remote systems that use `SystemTextJsonFormatter` when using the default UTF-8 encoding.
The remote party must also use the same message handler, such as `HeaderDelimitedMessageHandler`.

[MessagePackLibrary]: https://github.com/neuecc/MessagePack-CSharp
[MessagePackUsage]: ../src/StreamJsonRpc.Tests/MessagePackFormatterTests.cs
[MessagePackFormat]: https://msgpack.org/
[SystemTextJson]: https://learn.microsoft.com/dotnet/standard/serialization/system-text-json/overview
[spec]: https://www.jsonrpc.org/specification
Loading