Skip to content

Commit bc6f28c

Browse files
committed
Merge remote-tracking branch 'origin/master'
2 parents 76b10de + fd25123 commit bc6f28c

File tree

5 files changed

+110
-19
lines changed

5 files changed

+110
-19
lines changed

README.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,3 +186,61 @@ And here is a sample src/main/feature/feature.xml file to add some dependencies
186186
Here's an example of a GraphQL provider that implements three interfaces at the same time.
187187

188188
* [ExampleGraphQLProvider](examples/osgi/providers/src/main/java/graphql/servlet/examples/osgi/ExampleGraphQLProvider.java)
189+
190+
## Request-scoped DataLoaders
191+
192+
It is possible to use dataloaders in a request scope by customizing [GraphQLContextBuilder](https://github.com/graphql-java/graphql-java-servlet/blob/master/src/main/java/graphql/servlet/GraphQLContextBuilder.java).
193+
And instantiating a new [DataLoaderRegistry](https://github.com/graphql-java/java-dataloader/blob/master/src/main/java/org/dataloader/DataLoaderRegistry.java) for each GraphQLContext.
194+
For eg:
195+
```java
196+
public class CustomGraphQLContextBuilder implements GraphQLContextBuilder {
197+
198+
private final DataLoader userDataLoader;
199+
200+
public CustomGraphQLContextBuilder(DataLoader userDataLoader) {
201+
this.userDataLoader = userDataLoader;
202+
}
203+
204+
@Override
205+
public GraphQLContext build(HttpServletRequest req) {
206+
GraphQLContext context = new GraphQLContext(req);
207+
context.setDataLoaderRegistry(buildDataLoaderRegistry());
208+
209+
return context;
210+
}
211+
212+
@Override
213+
public GraphQLContext build() {
214+
GraphQLContext context = new GraphQLContext();
215+
context.setDataLoaderRegistry(buildDataLoaderRegistry());
216+
217+
return context;
218+
}
219+
220+
@Override
221+
public GraphQLContext build(HandshakeRequest request) {
222+
GraphQLContext context = new GraphQLContext(request);
223+
context.setDataLoaderRegistry(buildDataLoaderRegistry());
224+
225+
return context;
226+
}
227+
228+
private DataLoaderRegistry buildDataLoaderRegistry() {
229+
DataLoaderRegistry dataLoaderRegistry = new DataLoaderRegistry();
230+
dataLoaderRegistry.register("userDataLoader", userDataLoader);
231+
return dataLoaderRegistry;
232+
}
233+
}
234+
235+
```
236+
It is then possible to access the [DataLoader](https://github.com/graphql-java/java-dataloader/blob/master/src/main/java/org/dataloader/DataLoader.java) in the resolvers by accessing the [DataLoaderRegistry] from context. For eg:
237+
```java
238+
public CompletableFuture<String> getEmailAddress(User user, DataFetchingEnvironment dfe) { // User is the graphQL type
239+
final DataLoader<String, UserDetail> userDataloader =
240+
dfe.getContext().getDataLoaderRegistry().get().getDataLoader("userDataLoader"); // UserDetail is the data that is loaded
241+
242+
return userDataloader.load(User.getName())
243+
.thenApply(userDetail -> userDetail != null ? userDetail.getEmailAddress() : null);
244+
}
245+
246+
```

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
version = 6.1.3-SNAPSHOT
1+
version = 6.1.4
22
group = com.graphql-java
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package graphql.servlet;
2+
3+
import com.fasterxml.jackson.databind.InjectableValues;
4+
import com.fasterxml.jackson.databind.ObjectMapper;
5+
import com.fasterxml.jackson.databind.SerializationFeature;
6+
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
7+
8+
public class ConfiguringObjectMapperProvider implements ObjectMapperProvider {
9+
10+
private final ObjectMapperConfigurer objectMapperConfigurer;
11+
12+
public ConfiguringObjectMapperProvider(ObjectMapperConfigurer objectMapperConfigurer) {
13+
this.objectMapperConfigurer = objectMapperConfigurer;
14+
}
15+
16+
public ConfiguringObjectMapperProvider() {
17+
this.objectMapperConfigurer = new DefaultObjectMapperConfigurer();
18+
}
19+
20+
@Override
21+
public ObjectMapper provide() {
22+
ObjectMapper mapper = new ObjectMapper().disable(
23+
SerializationFeature.FAIL_ON_EMPTY_BEANS).registerModule(new Jdk8Module());
24+
objectMapperConfigurer.configure(mapper);
25+
26+
InjectableValues.Std injectableValues = new InjectableValues.Std();
27+
injectableValues.addValue(ObjectMapper.class, mapper);
28+
mapper.setInjectableValues(injectableValues);
29+
30+
return mapper;
31+
}
32+
}

src/main/java/graphql/servlet/GraphQLObjectMapper.java

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@
2525
* @author Andrew Potter
2626
*/
2727
public class GraphQLObjectMapper {
28-
private final Supplier<ObjectMapperConfigurer> objectMapperConfigurerSupplier;
28+
private final ObjectMapperProvider objectMapperProvider;
2929
private final Supplier<GraphQLErrorHandler> graphQLErrorHandlerSupplier;
3030

3131
private volatile ObjectMapper mapper;
3232

33-
protected GraphQLObjectMapper(Supplier<ObjectMapperConfigurer> objectMapperConfigurerSupplier, Supplier<GraphQLErrorHandler> graphQLErrorHandlerSupplier) {
34-
this.objectMapperConfigurerSupplier = objectMapperConfigurerSupplier;
33+
protected GraphQLObjectMapper(ObjectMapperProvider objectMapperProvider, Supplier<GraphQLErrorHandler> graphQLErrorHandlerSupplier) {
34+
this.objectMapperProvider = objectMapperProvider;
3535
this.graphQLErrorHandlerSupplier = graphQLErrorHandlerSupplier;
3636
}
3737

@@ -42,24 +42,13 @@ public ObjectMapper getJacksonMapper() {
4242
synchronized(this) {
4343
result = mapper;
4444
if (result == null) // Second check (with locking)
45-
mapper = result = createObjectMapper();
45+
mapper = result = objectMapperProvider.provide();
4646
}
4747
}
4848

4949
return result;
5050
}
5151

52-
private ObjectMapper createObjectMapper() {
53-
ObjectMapper mapper = new ObjectMapper().disable(SerializationFeature.FAIL_ON_EMPTY_BEANS).registerModule(new Jdk8Module());
54-
objectMapperConfigurerSupplier.get().configure(mapper);
55-
56-
InjectableValues.Std injectableValues = new InjectableValues.Std();
57-
injectableValues.addValue(ObjectMapper.class, mapper);
58-
mapper.setInjectableValues(injectableValues);
59-
60-
return mapper;
61-
}
62-
6352
/**
6453
* @return an {@link ObjectReader} for deserializing {@link GraphQLRequest}
6554
*/
@@ -163,15 +152,20 @@ public static Builder newBuilder() {
163152
}
164153

165154
public static class Builder {
166-
private Supplier<ObjectMapperConfigurer> objectMapperConfigurer = DefaultObjectMapperConfigurer::new;
155+
private ObjectMapperProvider objectMapperProvider = new ConfiguringObjectMapperProvider();
167156
private Supplier<GraphQLErrorHandler> graphQLErrorHandler = DefaultGraphQLErrorHandler::new;
168157

169158
public Builder withObjectMapperConfigurer(ObjectMapperConfigurer objectMapperConfigurer) {
170159
return withObjectMapperConfigurer(() -> objectMapperConfigurer);
171160
}
172161

173162
public Builder withObjectMapperConfigurer(Supplier<ObjectMapperConfigurer> objectMapperConfigurer) {
174-
this.objectMapperConfigurer = objectMapperConfigurer;
163+
this.objectMapperProvider = new ConfiguringObjectMapperProvider(objectMapperConfigurer.get());
164+
return this;
165+
}
166+
167+
public Builder withObjectMapperProvider(ObjectMapperProvider objectMapperProvider) {
168+
this.objectMapperProvider = objectMapperProvider;
175169
return this;
176170
}
177171

@@ -185,7 +179,7 @@ public Builder withGraphQLErrorHandler(Supplier<GraphQLErrorHandler> graphQLErro
185179
}
186180

187181
public GraphQLObjectMapper build() {
188-
return new GraphQLObjectMapper(objectMapperConfigurer, graphQLErrorHandler);
182+
return new GraphQLObjectMapper(objectMapperProvider, graphQLErrorHandler);
189183
}
190184
}
191185
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package graphql.servlet;
2+
3+
import com.fasterxml.jackson.databind.ObjectMapper;
4+
5+
public interface ObjectMapperProvider {
6+
ObjectMapper provide();
7+
}

0 commit comments

Comments
 (0)