Как исправить пустые объекты, возвращаемые API Giraffe, извлеченные из БД через SqlDataProvider - PullRequest
0 голосов
/ 11 ноября 2019

Я пытаюсь выучить F #, создав приложение F # с репозиторием для получения Упражнений для будущего Gym-приложения.

Я использую SqlServer для хранения данных и извлекаю данные с помощью Fsharp.Data.Sql. Модульные тесты для этого хорошо работают.

Я пытаюсь открыть данные через веб-API с помощью Giraffe, проблема в том, что я получаю список правильной длины, но с пустыми объектами внутри.

Вот контекст:

module Context

open FSharp.Data.Sql

let [<Literal>] dbVendor = Common.DatabaseProviderTypes.MSSQLSERVER
let [<Literal>] connectionString = "Server=DESKTOP-20JMHNK;Database=GymStrongDB;Trusted_Connection=True;"
let [<Literal>] indivAmount = 1000
let [<Literal>] useOptTypes  = true
let [<Literal>] owner = "public, admin, references"

type sql =
    SqlDataProvider<
        dbVendor,
        connectionString,
        "",
        "",
        indivAmount,
        useOptTypes,
        owner>

let gymStrongContext = sql.GetDataContext()

Вот репозиторий

namespace GymStrong.Repositories

open ...

module ExerciseRepository =
    let ctx = gymStrongContext.Dbo

    let getExercises = 
        ctx.Exercises |> Seq.toList

    let getExercisesHandler : HttpHandler =
        fun (next : HttpFunc) (ctx : HttpContext) ->
            Successful.OK getExercises next ctx

А вот соответствующая часть из Program.fs

open ...

let webApp =
    choose [
        GET >=> 
            choose [
                route "/" >=> text "Hello World"
                route "/user" >=> mustBeLoggedIn >=> getLoggedInUser
                route "/logout" >=> mustBeLoggedIn >=> logoutHandler
                route "/exercises" >=> mustBeLoggedIn >=> getExercisesHandler
                ]
        POST >=> 
            choose [
                route "/register" >=> registerHandler
                route "/login" >=> loginHandler
            ]
    ]

В юнит-тестах это работает правильно. Модульные тесты написаны на C #.

Когда я использую API через PostMan, я получаю этот ответ

[{},{}]

, который имеет правильную длину, так как у меня есть два упражнения в базе данных, но объекты кажутся пустыми.

1 Ответ

0 голосов
/ 12 ноября 2019

Это может быть полезно кому-то, поэтому я опубликую его.

И Жираф, и SqlDataProvider делают то, что должны. Проблема заключалась в том, что я думал, что могу передать предоставленный тип как json-ответ в API. Это неправильно, поскольку предоставленные типы не являются реальными типами и «стираются» (вместо Generated, который, как я думал, я работал).

Чтобы это исправить, мне нужно было сопоставить значения с «реальным» анемичным объектом DTO и передать его в качестве ответа. Теперь мне нужно выяснить, можно ли предоставить эти анемичные DTO-объекты на основе entityTypes, и можно ли их генерировать и использовать из других сборок.

Дополнительный код:

В хранилище / сервисе

    type exerciseDto = { 
        Id : string;
        Name : string;
        Description : string;
        Owner : string;
        Type : int; 
    }

    let getExercises = 
        ctx.Exercises |> Seq.map(fun exercise -> exercise.MapTo<exerciseDto>()) |> Seq.toList

И в program.cs

let handlerWrapper action : HttpHandler =
    fun (next : HttpFunc) (ctxHttp : HttpContext) ->
        Successful.OK action next ctxHttp

let webApp =
    choose [
        GET >=> 
            choose [
                route "/" >=> text "Hello World"
                route "/user" >=> mustBeLoggedIn >=> getLoggedInUser
                route "/logout" >=> mustBeLoggedIn >=> logoutHandler
                route "/exercises" >=> mustBeLoggedIn >=> handlerWrapper getExercises
                ]
        POST >=> 
            choose [
                route "/register" >=> registerHandler
                route "/login" >=> loginHandler
            ]
    ]

Надеюсь, это поможет любому сэкономить время вбудущее. Это заняло у меня как минимум несколько часов.

...