Skip to content

Instantly share code, notes, and snippets.

@davidfowl
Last active October 8, 2024 09:15
Show Gist options
  • Save davidfowl/41bcbccc7d8408af57ec1253ca558775 to your computer and use it in GitHub Desktop.
Save davidfowl/41bcbccc7d8408af57ec1253ca558775 to your computer and use it in GitHub Desktop.
Minimal + protobuf
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.WebUtilities;
using ProtoBuf;
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "POST a protobuf message to the /");
app.MapPost("/", (Proto<Person> p) => Results.Extensions.Protobuf(p.Item))
.Accepts<Person>("application/protobuf");
app.Run();
[ProtoContract]
class Person
{
[ProtoMember(1)]
public string? Name { get; set; }
}
// Input
public struct Proto<T>
{
public Proto(T item)
{
Item = item;
}
public T Item { get; }
public static async ValueTask<Proto<T>> BindAsync(HttpContext context)
{
// TODO: Check the content type?
// Unforutnately this serializer doesn't support async IO, we can buffer or we can allow sync IO
// this can cause performance problems for bigger payloads to buffering might be more appropriate.
// context.Features.Get<IHttpBodyControlFeature>()!.AllowSynchronousIO = true;
context.Request.EnableBuffering();
await context.Request.Body.DrainAsync(context.RequestAborted);
context.Request.Body.Position = 0;
var item = Serializer.Deserialize<T>(context.Request.Body);
return new(item);
}
}
// Output
public static class SerializerResultExtensions
{
public static IResult Protobuf<T>(this IResultExtensions _, T obj)
{
return new ProtobufResult<T>(obj);
}
private class ProtobufResult<T> : IResult
{
private readonly T _item;
public ProtobufResult(T item)
{
_item = item;
}
public Task ExecuteAsync(HttpContext httpContext)
{
httpContext.Response.ContentType = "application/protobuf";
// Unforutnately this serializer doesn't support async IO, we can buffer or we can allow sync IO
// this can cause performance problems for bigger payloads to buffering might be more appropriate.
httpContext.Features.Get<IHttpBodyControlFeature>()!.AllowSynchronousIO = true;
Serializer.Serialize(httpContext.Response.Body, _item);
return Task.CompletedTask;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment