Last active
October 8, 2024 09:15
-
-
Save davidfowl/41bcbccc7d8408af57ec1253ca558775 to your computer and use it in GitHub Desktop.
Minimal + protobuf
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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