FSharp.Data.GraphQL icon indicating copy to clipboard operation
FSharp.Data.GraphQL copied to clipboard

Passing EF Core db context to a field resolver

Open blackdwarf opened this issue 3 years ago • 1 comments

Looking at this document there seems to be a way to provide parameter to a field resolver outside of the GraphQL context. This seems like what I need to use in my Giraffe app to pass in the injected DbContext.

However, for the life of me, I cannot understand how to do this without the compiler complaining.

Has anyone else done this or is there some guide somewhere? The samples are not that useful, since the Star Wars API implementation uses static lists as data sources.

blackdwarf avatar Mar 20 '21 18:03 blackdwarf

Hi @blackdwarf

You can thread through an arbitrary value to your resolvers by passing it in when executing the query. e.g.:

executor.AsyncExecute(..., data=myRootValue)

this value is then accessible to your resolver via the context value (first parameter in your resolver), however, the value is untyped so you need to cast it. e.g.:

Define.Field("foo", String, "...", fun ctx _ -> 
    let dbContext = (ctx.Root :?> MyRoot).DbContext
    ...
)

To avoid always having to cast your Root value, you can always just add an extension member like so:

type ResolveFieldContext with
    member x.TypedRoot = x.Root :?> MyRoot

Hope that helps.

Thanks, John

jberzy avatar Mar 22 '21 06:03 jberzy

The latest StarWarsAPI project has a modified Root class. See Schema.fs file. Just declare a property on it and get EF from DI. Feel free to reopen if needed

xperiandri avatar Nov 05 '23 23:11 xperiandri