Rudi.Dev.FastEndpoints.MessagePack 1.1.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package Rudi.Dev.FastEndpoints.MessagePack --version 1.1.0                
NuGet\Install-Package Rudi.Dev.FastEndpoints.MessagePack -Version 1.1.0                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Rudi.Dev.FastEndpoints.MessagePack" Version="1.1.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Rudi.Dev.FastEndpoints.MessagePack --version 1.1.0                
#r "nuget: Rudi.Dev.FastEndpoints.MessagePack, 1.1.0"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Rudi.Dev.FastEndpoints.MessagePack as a Cake Addin
#addin nuget:?package=Rudi.Dev.FastEndpoints.MessagePack&version=1.1.0

// Install Rudi.Dev.FastEndpoints.MessagePack as a Cake Tool
#tool nuget:?package=Rudi.Dev.FastEndpoints.MessagePack&version=1.1.0                

Rudi.Dev.FastEndpoints.MessagePack

Add MessagePack Support to your FastEndpoints.

Why

  • Because MessagePack

Will it work with any FE project

Yup, most likely.

Usage

Add Rudi.Dev.FastEndpoints.MessagePack from NuGet.

To add support for input bindings globally, you need to call .AddMessagePackBinding() before .AddFastEndpoints(), and .ConfigureInboundMessagePack() to a global configurator within FastEndpoints.

For example:

builder.AddMessagePackBinding();
builder.Services.AddFastEndpoints();

// ...

app.UseFastEndpoints(c => {
    c.Endpoints.Configurator = ep => ep.ConfigureInboundMessagePack();
});

To enable support on a per-endpoint basis instead, don't setup the global configurator. Instead, configure your endpoint as follows:

public override void Configure()
{
    Description(o => o.Accepts<MyRequestObject>("application/x-msgpack"));
    
    // ..
}

To receive content at your endpoint, you need to set the Content-Type header of the request to application/msgpack, application/x-msgpack or application/vnd-msgpack. If you're using this, you're likely looking for performance, so use application/msgpack where possible as it will short-circuit quicker and save you approximately 4 attoseconds.

To send content from your endpoint via MessagePack, use this.SendAsMsgPackAsync(dto). With content-negotiation (ie. the Accept header must be one of the above), use this.SendWithMsgPackAsync(dto).

For example:

public override Task HandleAsync(CancellationToken ct)
{
    var myDto = new MyResponse { Something = "MessagePack Me!" };
    return this.SendAsMsgPackAsync(myDto); // or SendWithMsgPackAsync(myDto);
}

You can also override the default Response Serializer of FastEndpoints to work with content-negotiation only, as follows:

// Program
app.UseFastEndpoints(c => c.Serializer.ResponseSerializer = FastEndpointsResponseSerializer.MessagePack);

// Endpoint
return SendAsync(myDto); // will send as MessagePack if available in Accept header, or JSON otherwise

To override the MessagePack serializer options, for example if you wish to enable compression, just change it in the options:

builder.AddMessagePackBinding(o =>
    {
        o.SerializerOptions = new MessagePackSerializerOptions(StandardResolver.Instance)
            .WithCompression(MessagePackCompression.Lz4BlockArray);
    });

If you need to change the response header (for example for compatibility with another library that only reads application/x-msgpack), you can do this with:

builder.AddMessagePackBinding(o => o.DefaultResponseHeader = MessagePackConstants.XContentType);

Recommendations

By default, this uses MessagePack's Contractless resolver which allows you to change not very much (basically just the Program.cs) to get MessagePack serialization working.

Don't do this.

Instead, you should be decorating your DTOs with [MessagePackObject] and [Key(..)] attributes. This will allow you to use the StandardResolver which is more performant.

// Program
builder.AddMessagePackBinding(o => o.Resolver = StandardResolver.Instance);

// DTO
[MessagePackObject]
public class MyRequestObject {
    [Key(0)]
    public string MyProperty { get; set; }
    [Key(1)]
    public int AnotherProperty { get; set; }
    [Key(2)]
    public DateTime ADateProperty { get; set; }
}

What's supported

Everything, I think. If you think of anything, open up an issue / PR.

Troubleshooting

I'm getting a 415 Unsupported Media Type

Make sure you have set up the configurator correctly, like c.Endpoints.Configurator = ep => ep.ConfigureInboundMessagePack();.

Or wire the endpoint up manually as described above on a per-endpoint basis.

I'm still getting JSON in my responses

Are you using SendWithMsgPackAsync(..)? If so, make sure you have Accept: application/msgpack in your request headers. Or use SendAsMsgPackAsync(..) to force it.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.1.3 283 11/12/2023
1.1.2 141 11/12/2023
1.1.1 140 11/12/2023
1.1.0 145 11/12/2023
1.0.0 137 11/11/2023