https://kotlinlang.org logo
#graphql-kotlin
Title
# graphql-kotlin
d

dave08

02/21/2021, 12:28 PM
How do we handle DI in schemas? For queries, I'd suppose I could make it a Micronaut singleton, and inject repositories in it, but when types (data classes with functions for property resolution) need repos, it's a bit messy to inject them in each instance of a search result, or is that really the best practice here?
d

Dariusz Kuc

02/21/2021, 6:13 PM
For spring we provide spring aware data fetcher that can autowire spring beans as function arguments. You could probably do something similar for micronaut
Other than that - yeah you would need to inject it somehow
s

Shane Myrick

02/21/2021, 6:45 PM
As long as something is private or marked as
@GraphQLIgnore
in your query class you can still use what ever DI tool/format you are using today. In
graphql-kotlin-spring-server
we override the data fetcher and check if any function arguments are marked with
@Autowired
. This is a special feature for spring, but again we could just have every one handle their own DI through the constructor https://github.com/ExpediaGroup/graphql-kotlin/blob/b65d61a2123c02a04deb10aa8707fa[…]pediagroup/graphql/server/spring/execution/SpringDataFetcher.kt
j

Joe

02/21/2021, 9:08 PM
When schema types need repos, I've generally leant towards using DataLoaders that have injected fields and are accessible from the DataFetchingEnvironment in a resolver function, fwiw
d

dave08

02/22/2021, 10:33 AM
The
@AutoWired
approach looks interesting 🙂! The DataLoaders approach isn't too clear to me yet, I'll have to look into it, thanks! BeanAware can get to be lots of boilerplate, so I'm avoiding that... I saw it in one of the examples, in simple cases it's fine, but I would get to alot of clutter in my case...
s

Shane Myrick

02/22/2021, 5:43 PM
This is the traditional contructor approach I was mentioning that does require any special features and using DI through the contructor
Copy code
@Component
class ServiceQuery(private val userService: UserService) : Query {
    fun getUser(id: String) = userService.findUser(id)
}
d

dave08

02/23/2021, 3:10 AM
Yeah, that's fine, the problem really starts when you get further down into the results. But now that I think of it, one of my issues was filtering, which only needs agregation of the query. The real example that a repo would be needed is when completing results like fetching the friend list lazily. But that leads to another question: If the user's name, telephone, etc... would be functions to allow filtering on them, then either you need to collect all those filters somehow before running that query, or just stuff a UserFilterInput in getUser and repeat all the fields there...?
s

Shane Myrick

02/23/2021, 4:38 AM
You would need to do one of the following * Access the client query and any arguments with the
DataFetchingEnvironment
* Add arguments to your further down functions * Save the data at the top level in the context to be used later * Keep passing the top level arugments as private vars all the way down
2 Views