Rudi.Dev.FastEndpoints.MessagePack 1.0.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.0.0
NuGet\Install-Package Rudi.Dev.FastEndpoints.MessagePack -Version 1.0.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.0.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.0.0
#r "nuget: Rudi.Dev.FastEndpoints.MessagePack, 1.0.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.0.0

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

Rudi.Dev.FastEndpoints.MessagePack

Add MessagePack Support to your FastEndpoints.

Why

  • Because MessagePack

Will it work with any FE project

Probably, but you must be using .NET 8.0. Why? Because AcceptsMetadata wasn't public before. I could probably work around it, but it took long enough to get working as is.

If you're accepting MessagePack requests, this library has to adjust the endpoint registration. It's hacky as FE doesn't support [Consumes(..)] properly yet. If you're doing anything non-standard, there's a chance it won't work.

Usage

Add Rudi.Dev.FastEndpoints.MessagePack from NuGet.

To add support for input bindings, you need to call .AddMessagePackBinding() before .AddFastEndpoints(), and .UseEndpointsWithMessagePack() after .UseFastEndpoints().

For example:

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

// ...

app.UseFastEndpoints();
app.UseEndpointsWithMessagePack();

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);
    });

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 called UseEndpointsWithMessagePack() after UseFastEndpoints(), otherwise it can't tell ASP.NET to accept the content types required.

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 239 11/12/2023
1.1.2 101 11/12/2023
1.1.1 105 11/12/2023
1.1.0 110 11/12/2023
1.0.0 106 11/11/2023