F#으로 웹서버 API 만들기

3. 외부 REST API 서비스 호출하기 (이어서…)

POST 끝점에 DTO를 전달 할 수 있습니다.
전달 받을 record type을 선언합니다.

type UserRequestDto = {
    Name : string
    PhoneNumber : string
}

F#이 버전 업데이트 하면서 [<CLIMutable>] 어트리뷰트 없이도 역직렬화가 가능해졌습니다. 언제부터 가능했는지는 찾기 어렵군요. 정말 마음에 듭니다.

코드를 좀 더 고쳐 보겠습니다.

[<EntryPoint>]
let main _ =
    let app = webApp {
        ...
        
        post "/api/v2/users" (fun (httpContext: HttpContext) (req: UsersRequestDto) -> backgroundTask {
            use httpClient = httpContext.RequestServices.GetRequiredKeyedService<HttpClient>("reqres")

            let! response = httpClient.PostAsJsonAsync("/api/users", {|
                Name = req.Name
                PhoneNumber = req.PhoneNumber
            |})

            let! stream = response.Content.ReadAsStreamAsync()
            return Results.Stream(stream, contentType= $"{response.Content.Headers.ContentType}")
        })
    }

다음 요청에 대해 정상적으로 응답을 받을 수 있습니다.

POST http://localhost:5013/api/v2/users
Content-Type: application/json

{
    "name": "John Doe",
    "phoneNumber": "821000000000"
}

---

application/json; charset=utf-8, 98 bytes
{
  "name": "John Doe",
  "phoneNumber": "821000000000",
  "id": "334",
  "createdAt": "2025-04-04T06:29:45.398Z"
}

도메인 기반 타입 선언을 DTO에 반영해 보겠습니다. UserRequestDto를 수정해 봅니다.

type Name = Name of string
type InternationalPhoneNumber = InternationalPhoneNumber of string

type UsersRequestDto = {
    Name: Name
    PhoneNumber : InternationalPhoneNumber 
}

type Name = Name of stringtype Name = | Name of string을 줄여 쓴 표현이고 type Name = string과는 다릅니다.

수정한 코드는 F# 컴파일에 성공하지만 런타임에서 역직렬화에 실패합니다.
DU 에 대한 역질렬화는 F# CLR에 동작이 정의되어 있지 않습니다.

System.NotSupportedException: F# discriminated union serialization is not supported. Consider authoring a custom converter for the type. 

DU에 대한 직렬화를 위해 별개의 라이브러리를 추가합니다.

dotnet add package FSharp.SystemTextJson

(작성중…)

3개의 좋아요