Skip to content

Commit aaab887

Browse files
committed
Improved Serializer documentation
1 parent 8a3faa2 commit aaab887

6 files changed

Lines changed: 203 additions & 34 deletions

File tree

docs/serializers/.pages

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ nav:
33
- json.md
44
- bson.md
55
- xml.md
6+
- custom.md

docs/serializers/bson.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# BSON
22

3+
BSON (Binary JSON) serialization is available in the .NET implementation of TypedRest.
4+
35
=== "C#"
46

57
The BSON serializer provides efficient binary serialization using [Newtonsoft.Json](https://www.newtonsoft.com/json)'s BSON support:
@@ -16,3 +18,7 @@
1618
- String enums with camel-case naming
1719
- Null values are not serialized
1820
- Automatic type name handling
21+
22+
## Content type
23+
24+
The serializer handles the `application/bson` content type.

docs/serializers/custom.md

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
# Custom serializers
2+
3+
If none of the [built-in serializers](index.md) fits your needs, you can implement your own.
4+
5+
## Implement the interface
6+
7+
Implement the platform's `Serializer` interface (or appropriate base type):
8+
9+
=== "C#"
10+
11+
On .NET, TypedRest uses `MediaTypeFormatter` from the `System.Net.Http.Formatting` family. Derive from `MediaTypeFormatter` (or one of its specializations) and override the read/write methods.
12+
13+
```csharp
14+
using System.Net.Http.Formatting;
15+
16+
public class MySerializer : MediaTypeFormatter
17+
{
18+
public MySerializer()
19+
{
20+
SupportedMediaTypes.Add(new("application/my-format"));
21+
}
22+
23+
public override bool CanReadType(Type type) => true;
24+
public override bool CanWriteType(Type type) => true;
25+
26+
// Override ReadFromStreamAsync and WriteToStreamAsync to implement
27+
// custom (de)serialization logic.
28+
}
29+
```
30+
31+
=== "Java"
32+
33+
Implement the `net.typedrest.serializers.Serializer` interface or derive from `AbstractJsonSerializer` for JSON-based formats:
34+
35+
```java
36+
import net.typedrest.serializers.Serializer;
37+
import okhttp3.MediaType;
38+
import okhttp3.RequestBody;
39+
import okhttp3.ResponseBody;
40+
import java.util.List;
41+
42+
public class MySerializer implements Serializer {
43+
private static final MediaType MEDIA_TYPE = MediaType.get("application/my-format");
44+
45+
@Override
46+
public List<MediaType> getSupportedMediaTypes() {
47+
return List.of(MEDIA_TYPE);
48+
}
49+
50+
@Override
51+
public <T> RequestBody serialize(T entity, Class<T> type) {
52+
// Custom serialization logic
53+
return RequestBody.create(toBytes(entity), MEDIA_TYPE);
54+
}
55+
56+
@Override
57+
public <T> RequestBody serializeList(Iterable<T> entities, Class<T> type) {
58+
// Custom serialization logic
59+
return RequestBody.create(toBytes(entities), MEDIA_TYPE);
60+
}
61+
62+
@Override
63+
public <T> T deserialize(ResponseBody body, Class<T> type) {
64+
// Custom deserialization logic
65+
return fromBytes(body.bytes(), type);
66+
}
67+
68+
@Override
69+
public <T> List<T> deserializeList(ResponseBody body, Class<T> type) {
70+
// Custom deserialization logic
71+
return fromBytesAsList(body.bytes(), type);
72+
}
73+
}
74+
```
75+
76+
=== "Kotlin"
77+
78+
Implement the `net.typedrest.serializers.Serializer` interface or derive from `AbstractJsonSerializer` for JSON-based formats:
79+
80+
```kotlin
81+
import net.typedrest.serializers.Serializer
82+
import okhttp3.MediaType
83+
import okhttp3.MediaType.Companion.toMediaType
84+
import okhttp3.RequestBody
85+
import okhttp3.RequestBody.Companion.toRequestBody
86+
import okhttp3.ResponseBody
87+
88+
class MySerializer : Serializer {
89+
private val mediaType = "application/my-format".toMediaType()
90+
91+
override val supportedMediaTypes: List<MediaType> = listOf(mediaType)
92+
93+
override fun <T> serialize(entity: T, type: Class<T>): RequestBody =
94+
toBytes(entity).toRequestBody(mediaType)
95+
96+
override fun <T> serializeList(entities: Iterable<T>, type: Class<T>): RequestBody =
97+
toBytes(entities).toRequestBody(mediaType)
98+
99+
override fun <T> deserialize(body: ResponseBody, type: Class<T>): T? =
100+
fromBytes(body.bytes(), type)
101+
102+
override fun <T> deserializeList(body: ResponseBody, type: Class<T>): List<T>? =
103+
fromBytesAsList(body.bytes(), type)
104+
}
105+
```
106+
107+
=== "TypeScript"
108+
109+
Implement the `Serializer` interface from the `typedrest` package:
110+
111+
```typescript
112+
import { Serializer } from "typedrest";
113+
114+
class MySerializer implements Serializer {
115+
readonly supportedMediaTypes = ["application/my-format"];
116+
117+
serialize<T>(entity: T): string {
118+
// Custom serialization logic
119+
return JSON.stringify(entity);
120+
}
121+
122+
deserialize<T>(text: string): T {
123+
// Custom deserialization logic
124+
return JSON.parse(text) as T;
125+
}
126+
}
127+
```
128+
129+
## Content negotiation
130+
131+
The `supportedMediaTypes` property lists the MIME types this serializer can handle. TypedRest uses this information to:
132+
133+
- Set the `Content-Type` header when sending requests.
134+
- Set the `Accept` header when receiving responses.
135+
- Pick the right serializer for a response based on its `Content-Type` header (when multiple serializers are configured).
136+
137+
The first entry in the list is used as the default for outgoing requests.
138+
139+
## Register the serializer
140+
141+
Pass an instance of your serializer to the [entry endpoint](../endpoints/entry.md) constructor:
142+
143+
=== "C#"
144+
145+
```csharp
146+
var endpoint = new EntryEndpoint(
147+
new Uri("http://example.com/"),
148+
serializer: new MySerializer());
149+
```
150+
151+
=== "Java"
152+
153+
```java
154+
EntryEndpoint endpoint = new EntryEndpoint(
155+
URI.create("http://example.com/"),
156+
new MySerializer());
157+
```
158+
159+
=== "Kotlin"
160+
161+
```kotlin
162+
val endpoint = EntryEndpoint(
163+
URI.create("http://example.com/"),
164+
serializer = MySerializer())
165+
```
166+
167+
=== "TypeScript"
168+
169+
```typescript
170+
const endpoint = new EntryEndpoint(
171+
new URL("http://example.com/"),
172+
new MySerializer());
173+
```
174+
175+
All child endpoints created from this entry endpoint automatically inherit the serializer.

docs/serializers/index.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@
22

33
Serializers control how entities are serialized when sending requests and deserialized when receiving responses.
44

5-
TypedRest provides built-in serializers for various transport formats:
5+
TypedRest provides serializers for various transport formats:
66

7-
- [JSON](json.md)
8-
- [BSON](bson.md)
9-
- [XML](xml.md)
7+
| Format | C#/.NET | Java/Kotlin | TypeScript |
8+
| --------------- | -------- | ----------- | ---------- |
9+
| [JSON](json.md) | Built-in | Built-in | Built-in |
10+
| [XML](xml.md) | Built-in | Built-in | |
11+
| [BSON](bson.md) | Built-in | | |
1012

11-
You can also create and use custom serializers.
13+
You can also create and use [custom serializers](custom.md).
1214

1315
## Inheritance
1416

docs/serializers/json.md

Lines changed: 3 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,7 @@ JSON is the default serialization format in TypedRest.
3434

3535
**System.Text.Json**
3636

37-
You can also use the [System.Text.Json](https://learn.microsoft.com/en-us/dotnet/api/system.text.json) serializer with the [TypedRest.SystemTextJson](https://www.nuget.org/packages/TypedRest.SystemTextJson) NuGet package:
38-
39-
!!! note
40-
The `TypedRest.SystemTextJson` package version should match your main `TypedRest` package version. Both packages follow the same versioning scheme.
41-
37+
You can also use the [System.Text.Json](https://learn.microsoft.com/en-us/dotnet/api/system.text.json) serializer with the [TypedRest.SystemTextJson](https://www.nuget.org/packages/TypedRest.SystemTextJson) NuGet package.
4238
Default settings:
4339

4440
- Web defaults (camel-case property naming)
@@ -76,28 +72,6 @@ JSON is the default serialization format in TypedRest.
7672
// Uses JsonSerializer by default
7773
```
7874

79-
**Custom serializers**
80-
81-
You can implement the `Serializer` interface for custom serialization:
82-
83-
```typescript
84-
import { Serializer } from "typedrest";
75+
## Content type
8576

86-
class MySerializer implements Serializer {
87-
readonly supportedMediaTypes = ["application/json"];
88-
89-
serialize<T>(entity: T): string {
90-
// Custom serialization logic
91-
return JSON.stringify(entity);
92-
}
93-
94-
deserialize<T>(text: string): T {
95-
// Custom deserialization logic
96-
return JSON.parse(text) as T;
97-
}
98-
}
99-
100-
const endpoint = new EntryEndpoint(
101-
new URL("http://example.com/"),
102-
new MySerializer());
103-
```
77+
The serializer handles the `application/json` content type. TypedRest also automatically treats custom media types ending in `+json` (e.g., `application/vnd.api+json`, `application/hal+json`) as JSON and deserializes them using the configured JSON serializer.

docs/serializers/xml.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,19 @@
11
# XML
22

3+
XML serialization is available in the .NET implementation of TypedRest.
4+
35
=== "C#"
6+
The XML serializer uses .NET's built-in `System.Xml.Serialization.XmlSerializer`:
7+
48
```csharp
59
var endpoint = new EntryEndpoint(
610
new Uri("http://example.com/"),
711
serializer: new XmlSerializer());
812
```
13+
14+
## Content type
15+
16+
The serializer handles the following content types:
17+
18+
- `application/xml`
19+
- `text/xml`

0 commit comments

Comments
 (0)