Skip to content
This repository has been archived by the owner on Dec 19, 2023. It is now read-only.

Injecting Spring beans into data fetchers #20

Closed
mushketyk opened this issue Jul 21, 2017 · 7 comments
Closed

Injecting Spring beans into data fetchers #20

mushketyk opened this issue Jul 21, 2017 · 7 comments

Comments

@mushketyk
Copy link

mushketyk commented Jul 21, 2017

I am puzzled about how should I inject spring beans into data fetchers.
One way could be to pass ApplicationContext into graphQL.execute like this:

@Autowired
ApplicationContext applicationContext
...
graphQL.execute("{query}", applicationContext).<Map<String, Object>> getData()

Then DataFetcher implementation would look like:

class MovieDataFetcher implements DataFetcher<List<Item>> {

    @Override
    List<Item> get(DataFetchingEnvironment environment) {
        ApplicationContext applicationContext = environment.<ApplicationContext> getContext()
        MoviesRepository moviesRepository = applicationContext.getBean(MoviesRepository)
        return moviesRepository.findAll()
    }
}

What is the preferred way to do this with graphql-spring-boot?

@apottere
Copy link
Collaborator

That seems like a good solution. Right now, the servlet used doesn't expose a way to alter the context:

    @Override
    protected GraphQLContext createContext(Optional<HttpServletRequest> request, Optional<HttpServletResponse> response) {
        return new GraphQLContext(request, response);
    }

That could be extended to allow you to pass your own context creator that adds the applicationContext.

Static datafetchers are annoying, which is why I created my own library (https://github.com/graphql-java/graphql-java-tools) that let you have state, which means you can @Autowire beans into them.

@mushketyk
Copy link
Author

Hi @apottere
Thank you for the response.

I think it would be a good idea to allow altering the context to increase application flexibility.
Regarding graphql-java-tools. Does it work with graphql-annotations?

@apottere
Copy link
Collaborator

No, it's not compatible with annotations. They're both graphql-schema generation libraries, but they have different philosophies :)

@apottere
Copy link
Collaborator

Currently releasing this: graphql-java-kickstart/graphql-java-servlet@0b62669

Once that's done, I'll update this project to expose it.

@mushketyk
Copy link
Author

Thank you for the update @apottere. I think this commit may help to close #5 as well!

@mushketyk
Copy link
Author

mushketyk commented Jul 24, 2017

A temporary workaround is to use graphql-java-servlet instead of graphql-spring-boot and define these beans:

    // Register GraphQL servlet
    @Bean
    ServletRegistrationBean servletRegistrationBean() {
        return new ServletRegistrationBean(graphQLServlet(), "/graphql/*");
    }

    @Bean
    GraphQLServlet graphQLServlet() {
        // Return custom GraphQL context
        new SimpleGraphQLServlet(graphQLSchema()) {
            @Override
            protected GraphQLContext createContext(Optional<HttpServletRequest> request, Optional<HttpServletResponse> response) {
                return new SpringGraphQLContext(request, response, applicationContext);
            }
        }
    }

and SpringGraphQLContext would look like this:

class SpringGraphQLContext extends GraphQLContext {

    private ApplicationContext applicationContext

    SpringGraphQLContext(Optional<HttpServletRequest> request,
                         Optional<HttpServletResponse> response,
                         ApplicationContext applicationContext) {
        super(request, response);
        this.applicationContext = applicationContext;
    }

    ApplicationContext getApplicationContext() {
        return applicationContext;
    }
}

than one can access ApplicationContext in a data fetcher:

List<Movie> get(DataFetchingEnvironment environment) {
    ApplicationContext applicationContext = environment.<SpringGraphQLContext> getContext().getApplicationContext()
}

@apottere
Copy link
Collaborator

graphql-spring-boot 3.6.0 is released, and allows you to specify a GraphQLContextBuilder bean.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants