Skip to content

Commit

Permalink
Moved serialization documentation, added additional examples and context
Browse files Browse the repository at this point in the history
  • Loading branch information
phatboyg committed May 22, 2023
1 parent 477f369 commit 576a292
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 78 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -148,23 +148,3 @@ public record ReformatHardDrive :
{
}
```

### MessageUrn

_MessageUrn_ is an optional attribute that may be specified on a message type to provide a custom Urn that will be used when the message is published or consumed. The generated Urn will be prefixed with `urn:messages:` by default, however a full Urn may be provided by specifying `useDefaultPrefix: false` in the attribute declaration.

```csharp
[MessageUrn("publish-command")]
public record PublishCommand
{
// Will generate a urn of: urn:messages:publish-command
}
```

```csharp
[MessageUrn("scheme:publish-command", useDefaultPrefix: false)]
public record PublishCommand
{
// Will generate a urn of: scheme:publish-command
}
```
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,82 @@ navigation.title: Serialization

# Message Serialization

In MassTransit, developers specify types for messages. MassTransit's serializers then perform the hard work of converting the types to the serializer format (
such as JSON, XML, BSON, etc.) and then back again.
MassTransit uses _types_ for [messages](/documentation/concepts/messages). Serializers are used convert those types into their respective format (such as JSON, XML, BSON, etc.), which is sent to the message broker. A corresponding deserializer is then used to convert the serialized format back into a type.

To interoperate with other languages and platforms, the message structure is important.
By default, MassTransit uses _System.Text.Json_ to serialize and deserialize messages using JSON.

## Supported Serializers

MassTransit include support for several commonly used serialization packages.

### System.Text.Json

_System.Text.Json_ is the default message serializer/deserializer.

| Content Type | Format | Configuration Method |
|:-------------------------------------|:----------------------|:----------------------------------|
| **application/vnd.masstransit+json** | **JSON (w/envelope)** | `UseJsonSerializer` **(default)** |
| application/json | JSON | `UseRawJsonSerializer` |

### Newtonsoft

The [MassTransit.Newtonsoft](https://nuget.org/packages/MassTransit.Newtonsoft) package adds the serialization formats listed below.

> In MassTransit versions before v8, Newtonsoft was the default message serializer/deserializer.
| Content Type | Format | Configuration Method |
|:-----------------------------------|:--------------------|:---------------------------------|
| application/vnd.masstransit+json | JSON (w/envelope) | `UseNewtonsoftJsonSerializer` |
| application/json | JSON | `UseNewtonsoftRawJsonSerializer` |
| application/vnd.masstransit+bson | BSON (w/envelope) | `UseBsonSerializer` |
| application/vnd.masstransit+xml | XML (w/envelope) | `UseXmlSerializer` |
| application/xml | XML | `UseRawXmlSerializer` |
| application/vnd.masstransit+aes | Binary (w/envelope) | `UseEncryptedSerializer` |
| application/vnd.masstransit.v2+aes | Binary (w/envelope) | `UseEncryptedSerializerV2` |


## Message Types

MassTransit stores the supported .NET types for a message as an array of URNs, which include the namespace and name of the message type. All interfaces and
superclasses of the message type are included. The namespace and name are formatted as shown below.

`urn:message:Namespace:TypeName`

A few examples of valid message types:

```text
urn:message:MyProject.Messages:UpdateAccount
urn:message:MyProject.Messages.Events:AccountUpdated
urn:message:MyProject:ChangeAccount
urn:message:MyProject.AccountService:MyService+AccountUpdatedEvent
```

> The last one is a nested class, as indicated by the '+' symbol.

### MessageUrn Attribute

_MessageUrn_ is an optional attribute that may be specified on a message type to provide a custom Urn that will be used when the message is published or consumed. The generated Urn will be prefixed with `urn:messages:` by default, however a full Urn may be provided by specifying `useDefaultPrefix: false` in the attribute declaration.

```csharp
[MessageUrn("publish-command")]
public record PublishCommand
{
// Will generate a urn of: urn:messages:publish-command
}
```

```csharp
[MessageUrn("scheme:publish-command", useDefaultPrefix: false)]
public record PublishCommand
{
// Will generate a urn of: scheme:publish-command
}
```

## Message Envelope

MassTransit encapsulates messages in an envelope before they are serialized. An example JSON message envelope is shown below:
To interoperate with other languages and platforms, message structure is important. MassTransit encapsulates messages in an envelope before they are serialized. An example JSON message envelope is shown below.

```json
{
Expand Down Expand Up @@ -66,27 +134,11 @@ MassTransit encapsulates messages in an envelope before they are serialized. An

> Set indicates whether the property is automatically set by MassTransit when producing messages. _Yes_, _Requests_ only, or _Situational_.
### Message Type

MassTransit stores the supported .NET types for a message as an array of URNs, which include the namespace and name of the message type. All interfaces and
superclasses of the message type are included. The namespace and name are formatted as shown below.

`urn:message:Namespace:TypeName`

A few examples of valid message types:

```text
urn:message:MyProject.Messages:UpdateAccount
urn:message:MyProject.Messages.Events:AccountUpdated
urn:message:MyProject:ChangeAccount
urn:message:MyProject.AccountService:MyService+AccountUpdatedEvent
```

> The last one is a nested class, as indicated by the '+' symbol.
## Raw JSON

When using a serializer that doesn't wrap the message in an envelope (_application/json_), the above message would be reduced to the simple JSON below.
Consuming messages from other systems where messages may not be produced by MassTransit, raw JSON is commonly used.

When using a serializer that doesn't wrap the message in an envelope (_application/json_), the above message would be reduced to the raw JSON shown below.

```json
{
Expand All @@ -95,7 +147,35 @@ When using a serializer that doesn't wrap the message in an envelope (_applicati
}
```

If the _RawSerializerOptions.AddTransportHeaders_ option is specified when configuring a raw JSON serializer, the following transport headers will be set if the header value is present.
::callout{type="info"}
#summary
Learn more about using raw JSON messages in this video.

#content
::div
:video-player{src="https://www.youtube.com/watch?v=xOxSLNeN5CU"}
::
::

### Options

MassTransit provides several options when dealing with raw JSON messages. The options can be specified on the _UseRawJsonSerializer_ method._RawSerializerOptions_ includes the following flags:

| Option | Value | Default | Notes |
|:--------------------|:-----:|:-------:|:-------------------------------------------------------------|
| AnyMessageType | 1 | Y | Messages will match any consumed message type |
| AddTransportHeaders | 2 | Y | MassTransit will add the above headers to outbound messages |
| CopyHeaders | 4 | N | Received message headers will be copied to outbound messages |

In cases where MassTransit is used and raw JSON messages are preferred, the non-default options are recommended.

```csharp
cfg.UseRawJsonSerializer(RawSerializerOptions.AddTransportHeaders | RawSerializerOptions.CopyHeaders);
```

### Headers

When the _RawSerializerOptions.AddTransportHeaders_ option is specified, the following transport headers will be set (if not empty or default).

| Header Name | Type | Notes |
|:---------------------|:--------:|:----------------------------------------------------------|
Expand All @@ -111,44 +191,26 @@ If the _RawSerializerOptions.AddTransportHeaders_ option is specified when confi
| MT-Host-Info | string | JSON serialized host info |
| MT-OriginalMessageId | Guid | For redelivered messages with a newly generated MessageId |

MassTransit provides several options when dealing with raw JSON messages. The options can be specified on the _UseRawJsonSerializer_ method._RawSerializerOptions_ includes the following flags:
### Configuration

| Option | Value | Default | Notes |
|:--------------------|:-----:|:-------:|:-------------------------------------------------------------|
| AnyMessageType | 1 | Y | Messages will match any consumed message type |
| AddTransportHeaders | 2 | Y | MassTransit will add the above headers to outbound messages |
| CopyHeaders | 4 | N | Received message headers will be copied to outbound messages |
::alert{type="info"}
Serialization customizations for using raw JSON is generally recommended on individual receive endpoints only, vs being globally configured at the bus level.
::

In cases where MassTransit is used and raw JSON messages are preferred, the non-default options are recommended.
To configure a receive endpoint so that it can _receive_ raw JSON messages, specify the default content type and add the deserializer as shown below. When a raw JSON message is received, it will be delivered to every consumer configured on the receive endpoint.

```csharp
cfg.UseRawJsonSerializer(RawSerializerOptions.AddTransportHeaders | RawSerializerOptions.CopyHeaders);
endpointConfigurator.DefaultContentType = new ContentType("application/json");
endpointConfigurator.UseRawJsonDeserializer();
```

## Serializers

MassTransit include support for several commonly used serialization packages.

### System Text Json

MassTransit uses _System.Text.Json_ by default to serialize and deserialize JSON messages.

| Content Type | Format | Configuration Method |
|:-------------------------------------|:----------------------|:----------------------------------|
| **application/vnd.masstransit+json** | **JSON (w/envelope)** | `UseJsonSerializer` **(default)** |
| application/json | JSON | `UseRawJsonSerializer` |
If messages produced by consumers on the receive endpoint should also be in the raw JSON format, `UseRawJsonSerializer()` may be used instead.

### Newtonsoft
Setting the default content type tells MassTransit to use the raw JSON deserializer for messages that do not have a recognized `Content-Type` header.

The [MassTransit.Newtonsoft](https://nuget.org/packages/MassTransit.Newtonsoft) package adds the following serializer types. Prior to MassTransit v8, Newtonsoft was the default message serializer.
To prevent MassTransit from creating exchanges or topics for the message types consumed on the endpoint, disable consume topology configuration.

| Content Type | Format | Configuration Method |
|:-----------------------------------|:--------------------|:---------------------------------|
| application/vnd.masstransit+json | JSON (w/envelope) | `UseNewtonsoftJsonSerializer` |
| application/json | JSON | `UseNewtonsoftRawJsonSerializer` |
| application/vnd.masstransit+bson | BSON (w/envelope) | `UseBsonSerializer` |
| application/vnd.masstransit+xml | XML (w/envelope) | `UseXmlSerializer` |
| application/xml | XML | `UseRawXmlSerializer` |
| application/vnd.masstransit+aes | Binary (w/envelope) | `UseEncryptedSerializer` |
| application/vnd.masstransit.v2+aes | Binary (w/envelope) | `UseEncryptedSerializerV2` |
```csharp
endpointConfigurator.ConfigureConsumeTopology = false;
```

8 changes: 5 additions & 3 deletions doc/server/middleware/redirects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,8 @@ const mapping: { [key: string]: string } = {
'/architecture/packages.html': '/support/packages',
'/architecture/green-cache.html': '/documentation/concepts/messages',
'/architecture/nservicebus.html': '/documentation/configuration/integrations/nsb',
'/architecture/interoperability.html': '/documentation/configuration/integrations/serialization',
'/advanced/interoperability.html': '/documentation/configuration/integrations/serialization',
'/architecture/interoperability.html': '/documentation/configuration/serialization',
'/advanced/interoperability.html': '/documentation/configuration/serialization',
'/architecture/history.html': '/documentation/concepts/messages',
'/architecture/encrypted-messages.html': '/documentation/concepts/messages',
'/architecture/newid.html': '/documentation/patterns/newid',
Expand All @@ -208,7 +208,9 @@ const mapping: { [key: string]: string } = {
'/getting-started/upgrade-v6.html': '/support/upgrade',
'/getting-started/index.html': '/documentation/concepts/messages',
'/getting-started/live-coding.html': '/documentation/concepts/messages',
'/discord.html': '/support/support-channels'
'/discord.html': '/support/support-channels',

'/documentation/configuration/integrations/serialization': '/documentation/configuration/serialization'
}

// flip the map, so we ignore good routes
Expand Down

0 comments on commit 576a292

Please sign in to comment.