💎

それ、F#でやってみました - ASP.NET Core Minimal API

2024/04/26に公開

ASP.NET Core Minimal APIを使ってF#でHTTPサーバアプリケーションを作成してみました。HTTPSからHTTPへのリダイレクトを使用していますが、HTTPS通信は開発環境用ですのでご注意ください。

開発環境を作成、実行
dotnet new web -lang f# -o miniweb
cd miniweb

(Program.fsを編集)

dotnet run
Program.fs
open System
open System.Text
open System.Text.Json
open Microsoft.AspNetCore.Builder
open Microsoft.AspNetCore.Http

[<EntryPoint>]  // 実行開始位置
let main args =
    // ASP.NET Core Minimal APIによるHTTPサーバアプリケーションの構築
    let builder = WebApplication.CreateBuilder(args)
    let app = builder.Build()

    // アクセスされるURL (HTTPからHTTPSへのリダイレクト含む)
    [
        "https://127.0.0.1:5443"    // self-signed certificate
        "http://127.0.0.1:5080"
    ] |> List.iter app.Urls.Add

    // HTTPからHTTPSへのリダイレクト(ignoreは戻り値を無視)
    app.UseHttpsRedirection() |> ignore

    [
        // テキストの出力
        ("/", Func<IResult>(fun () -> Results.Ok "Hello F#!"))
        // HTMLの出力
        ("/html/hello", Func<IResult>(fun () ->
            Results.Content("<html><body>こんにちはF#!</body></html>",
                            "text/html;charset=UTF-8")))
        // JSONの出力(匿名レコード)
        ("/json/hello", Func<IResult>(fun () ->
            Results.Json {| message = "こんにちはF#!" |}))
        // リダイレクト
        ("/redirect/hello", Func<IResult>(fun () ->
            Results.Redirect "/html/hello"))
     ] |> List.iter (app.MapGet >> ignore)

    // リクエストのテキストをそのままレスポンスで返す
    app.MapPost("/echo", Func<HttpContext, IResult>(fun ctx ->
        let request = ctx.Request
        let response = ctx.Response
        if (request.ContentType.IndexOf("application/json") >= 0) then
            // JSONで出力(文字列とオブジェクトの変換)
            let json = JsonSerializer.DeserializeAsync(request.Body).Result
            Results.Json json
        else
            // テキストで出力
            let len = int request.ContentLength.Value
            let bytes = Array.zeroCreate<byte> len
            request.Body.ReadAsync(bytes, 0, len).Wait()
            Results.Content(Encoding.UTF8.GetString(bytes), request.ContentType)
    )) |> ignore

    // サーバ起動
    app.Run()

    0 // Exit code
結果
$ curl -kL http://127.0.0.1:5080/
"Hello F#!"

$ curl -k https://127.0.0.1:5443/
"Hello F#!"

$ curl -k https://127.0.0.1:5443/html/hello
<html><body>こんにちはF#!</body></html>

$ curl -k https://127.0.0.1:5443/json/hello
{"message":"こんにちはF#!"}

$ curl -kL https://127.0.0.1:5443/redirect/hello
<html><body>こんにちはF#!</body></html>

$ curl -k https://127.0.0.1:5443/echo \
  -H 'text/plain;charset=UTF-8' \
  -d 'こんにちはMinimal API!'
こんにちはMinimal API!

$ curl -k https://127.0.0.1:5443/echo \
  -H 'application/json;charset=UTF-8' \
  -d '{"message":"こんにちはMinimal API!"}'
{"message":"こんにちはMinimal API!"}

Discussion