Concerns

Concerns allow to add behavior to a section of your web application by intercepting requests and responses. The framework allows any handler to be extended by using concerns. The following example will add a custom HTTP header to every response generated by the server:

using GenHTTP.Engine.Internal;
using GenHTTP.Modules.IO;

var customConcern = Concern.From(async (request, content) =>
{
    var response = await content.HandleAsync(request);

    response?.Headers.Add("X-Custom-Header", "Custom Concern");

    return response;
});

var handler = Content.From(Resource.FromString("Hello World"))
                     .Add(customConcern);

await Host.Create()
          .Handler(handler)
          .RunAsync();

This code uses a shortcut provided by the Concern class of the IO module to reduce the boilerplate required to implement IConcern. The full version of the example above would look like this:

using GenHTTP.Api.Content;
using GenHTTP.Api.Protocol;

using GenHTTP.Engine.Internal;

using GenHTTP.Modules.IO;

var handler = Content.From(Resource.FromString("Hello World"))
                     .Add(new CustomConcernBuilder());

await Host.Create()
          .Handler(handler)
          .RunAsync();

public class CustomConcern : IConcern
{

    public IHandler Content { get; }

    public CustomConcern(IHandler content)
    {
        Content = content;
    }

    public ValueTask PrepareAsync() => Content.PrepareAsync();

    public async ValueTask<IResponse?> HandleAsync(IRequest request)
    {
        var response = await Content.HandleAsync(request);

        if (response != null)
        {
            response.Headers.Add("X-Custom-Header", "Custom Concern");
        }

        return response;
    }

}

public class CustomConcernBuilder : IConcernBuilder
{

    public IConcern Build(IHandler content)
    {
        return new CustomConcern(content);
    }

}

The GenHTTP SDK uses the same mechanism to achieve functionality such as compression or support for CORS.