BitBadger.Documents/docs/advanced/custom-serialization.md

39 lines
2.7 KiB
Markdown

# Custom Serialization
_<small>Documentation pages for `BitBadger.Npgsql.Documents` redirect here. This library replaced it as of v3; see project home if this applies to you.</small>_
JSON documents are sent to and received from both PostgreSQL and SQLite as `string`s; the translation to and from your domain objects (commonly called <abbr title="Plain Old CLR Objects">POCO</abbr>s) is handled via .NET. By default, the serializer used by the library is based on `System.Text.Json` with [converters for common F# types][fs].
## Implementing a Custom Serializer
`IDocumentSerializer` (found in the `BitBadger.Documents` namespace) specifies two methods. `Serialize<T>` takes a `T` and returns a `string`; `Deserialize<T>` takes a `string` and returns an instance of `T`. (These show as `'T` in F#.) While implementing those two methods is required, the custom implementation can use whatever library you desire, and contain converters for custom types.
Once this serializer is implemented and constructed, provide it to the library:
```csharp
// C#
var serializer = /* constructed serializer */;
Configuration.UseSerializer(serializer);
```
```fsharp
// F#
let serializer = (* constructed serializer *)
Configuration.useSerializer serializer
```
The biggest benefit to registering a serializer (apart from control) is that all JSON operations will use the same serializer. This is most important for PostgreSQL's JSON containment queries; the object you pass as the criteria will be translated properly before it is compared. However, "unstructured" data does not mean "inconsistently structured" data; if your application uses custom serialization, extending this to your documents ensures that the structure is internally consistent.
## Uses for Custom Serialization
- If you use a custom serializer (or serializer options) in your application, a custom serializer implementation can utilize these existing configuration options.
- If you prefer [`Newtonsoft.Json`][nj], you can wrap `JsonConvert` or `JsonSerializer` calls in a custom converter. F# users may consider incorporating Microsoft's [`FSharpLu.Json`][fj] converter.
- If your project uses [`NodaTime`][], your custom serializer could include its converters for `System.Text.Json` or `Newtonsoft.Json`.
- If you use <abbr title="Domain Driven Design">DDD</abbr> to define custom types, you can implement converters to translate them to/from your preferred JSON representation.
[fs]: https://github.com/Tarmil/FSharp.SystemTextJson "FSharp.SystemTextJson • GitHub"
[nj]: https://www.newtonsoft.com/json "Json.NET"
[fj]: https://github.com/microsoft/fsharplu/blob/main/FSharpLu.Json.md "FSharpLu.Json • GitHub"
[`NodaTime`]: https://nodatime.org/ "NodaTime"