Search code examples
javagraphqlgraphql-java

Create Per Request Data Loaders in GraphQL Java


I am using GraphQL to create an API that queries some endpoints. Right now the way that the DataLoader is setup, the values in the cache persist across multiple web requests. As suggested in the docs, I want to change that so that DataLoaders are scoped per request - i.e cache data from one request is not visible to another request. The docs do not explicitly give an example on how to go about doing this.

I see this link: https://github.com/graphql-java/java-dataloader/issues/19 ..and I was wondering if this is still the correct/only way to go? Or is there some another way as well?

Thanks.


Solution

  • It is still the same idea.

    To process a GraphQL request , you have to create a new ExecutionInput instance and configure its setting for every request. One of its setting is the Context object (It is a generic Object type and so you are free to define your own type). Just make sure that this Context object contain a DataLoaderRegistry and ensure that you create a new instance of Context with the new instance of DataLoaderRegistry that register a new instance of DataLoader to it.

    Code wise, it looks likes:

    public class MyContext {
        private DataLoaderRegistry dataLoaderRegistry;
    
        public MyContext(DataLoaderRegistry dataLoaderRegistry){
            this.dataLoaderRegistry = dataLoaderRegistry;
        }
    }
    
    //Process a GraphQL request
    
    DataLoaderRegistry dataLoaderRegistry = new DataLoaderRegistry();
    dataLoaderRegistry.register("fooDataLoder" , DataLoader.newDataLoader("......."));
    
    MyContext context = new MyContext(dataLoaderRegistry);
    
    
    ExecutionInput executionInput = ExecutionInput.newExecutionInput()
                    .query("employees {id name department}")
                    .context(context)
                    .dataLoaderRegistry(context.getDataLoaderRegistry())
                    .build();
    
     GraphQL graphQL = GraphQL.newGraphQL(schema).build();
     ExecutionResult executionResult = graphQL.execute(executionInput);
    
    

    A small difference is that in some later version of , you do not need to explicitly configure DataLoaderDispatcherInstrumentation for the GraphQL like this as it will be automatically activated if it is not configured. Instead, just make sure you configure the same dataLoaderRegistry for the ExecutionInput that you set for the Context because DataLoaderDispatcherInstrumentation need to access DataLoaderRegistry from it.