skip to Main Content

I’m working on developing an F# wrapper for ASP.NET Core’s minimal API to make route handlers more idiomatic to F#. My current implementation for a simple GET endpoint looks traditionally C#-ish:
app.MapGet("/", Func<Http.HttpContext, string>(fun _ -> "Hello World!"))

I’m aiming for a more F#-native syntax, something along the lines of:
app |> mapGet<'returnType> "/" (fun _ -> "Hello World!")

To achieve this, I started writing a wrapper function like so:

let mapGet<'returnType> (pattern: string) func (app: WebApplication) =
    app.MapGet(pattern, Func<Http.HttpContext, 'returnType>(func))

This works well for endpoints that don’t require path parameters. However, I’m encountering difficulties when trying to extend this pattern to support route parameters, such as an ID. Specifically, I want to adapt the function to handle endpoints like /api/item/{id}, where id could be an int, Guid, or any other type, and ensure the func parameter appropriately includes these route parameters in its signature.

Here’s an illustrative example of what I’m trying to accomplish:
app |> mapGet<string> "/api/item/{id:int}" (fun (httpContext: Http.Context) (id: int) -> "hello world" + id)

2

Answers


  1. This should work for a single route parameter:

    let uncurry f (a, b) = f a b
    
    let mapGet1<'returnType, 'arg> (pattern: string) func (app: WebApplication) =
        app.MapGet(
            pattern,
            Func<Http.HttpContext * 'arg, 'returnType>(uncurry func))
    

    Test:

    app
        |> mapGet1
            "/api/item/{id:int}"
            (fun _httpContext (id: int) ->
                "hello world" + string id)
    

    You can extend the pattern for more parameters, but you’ll have to give each version a unique name (e.g. mapGet2, mapGet3, etc.).

    Login or Signup to reply.
  2. Have you checked the Oxpecker package? It should work well with what you need and also supports specifying input/return types for OpenApi schema

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search