Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unexpected empty response when using Response.ofJson / Response.ofJsonOptions #125

Open
aggieben opened this issue Jul 3, 2024 · 0 comments

Comments

@aggieben
Copy link

aggieben commented Jul 3, 2024

I have an application set up to use FSharp.Data.GraphQL - a pretty simple graphql API with the one endpoint, and a simple query. The key bit here is that the handler handleGraphQL gets a response back from the GraphQL executor, and then tries to serialize it into Json. However, the result is empty.

I've been able to break into the debugger to prove to myself that data (in the case for Direct (data, _)) is an IDictionary populated with the results of the query, and serializes to something reasonable by simply calling System.Text.Json.JsonSerializer.Serialize(data, jsonOptions):

image

However, where I complete the handler I call Response.ofJsonOptions jsonOptions data, and the resulting response is ....nothing at all.

Any hints as to what might be going on there?

module SmartTransact.Api.Program

type private Marker = interface end
let internal moduleType = typeof<Marker>.DeclaringType

open System
open System.Data
open System.Net.Mime
open System.Text.Json.Nodes
open System.Text.Json.Serialization
open System.Threading.Tasks
open Microsoft.AspNetCore.Builder
open Microsoft.AspNetCore.Http
open Microsoft.AspNetCore.HttpLogging
open Microsoft.Extensions.DependencyInjection
open Microsoft.Extensions.Logging

open Falco
open Falco.Routing
open Falco.HostBuilder
open FSharp.Data.GraphQL
open Npgsql

open Utility


let jsonOptions = JsonFSharpOptions.Default().ToJsonSerializerOptions()

let config = configuration [||] {
    required_json "appsettings.json"
    add_env
}

let getGraphQLQuery contentType (body:string) =
    async {
        match contentType with
        | MediaTypeNames.Application.Json ->
            let jsonNode = JsonNode.Parse(body)
            return jsonNode["query"].ToString()
        | _ -> return body
    }

let rec handleGraphQL (ctx:HttpContext) =
    task {
        let! body = Request.getBodyString ctx
        let! query = getGraphQLQuery ctx.Request.ContentType body
        let! result = Schema.executor (Schema.Root(ctx)) query

        return
            match result.Content with
            | Direct (data,_) ->
                Response.ofJsonOptions jsonOptions data
            | Deferred (_,_,_) -> Response.ofJsonOptions jsonOptions "deferred"
            | Stream _ -> Response.ofJsonOptions jsonOptions "stream"
            | RequestError _ -> Response.ofJsonOptions jsonOptions "error"
    } :> Task

let configuration (services:IServiceCollection) =
    services.AddSingleton config

let logger (services:IServiceCollection) =
    services.AddLogging()

let dataSource (services:IServiceCollection) =
    let connectionString = config["ConnectionStrings:Default"]
    printfn "get connection string: %s" connectionString
    let ds = Npgsql.NpgsqlDataSource.Create(connectionString)
    services
        .AddSingleton(ds)
        .AddScoped<IDbConnection>(
            fun (sp:IServiceProvider) -> sp.GetRequiredService<NpgsqlDataSource>().CreateConnection())

let httpLogging (services:IServiceCollection) =
    services.AddHttpLogging(fun opts -> ())

[<EntryPoint>]
let main args =

    webHost args {
        add_service configuration
        add_service dataSource
        add_service httpLogging

        use_middleware (fun app -> app.UseHttpLogging())

        endpoints [
            get "/" (Response.ofPlainText "Hello world")
            post "/graphql" handleGraphQL
        ]
    }
    0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant