Skip to content

Commit

Permalink
Passing DataLoaderRegistry as the query context. This allow us to avo…
Browse files Browse the repository at this point in the history
…id using the request scope.
  • Loading branch information
siderakis committed Mar 21, 2018
1 parent d214ac9 commit 993c661
Show file tree
Hide file tree
Showing 11 changed files with 55 additions and 33 deletions.
Expand Up @@ -22,7 +22,6 @@
import com.google.example.library.book.v1.ListBooksRequest; import com.google.example.library.book.v1.ListBooksRequest;
import com.google.inject.AbstractModule; import com.google.inject.AbstractModule;
import com.google.inject.Provides; import com.google.inject.Provides;
import com.google.inject.servlet.RequestScoped;
import net.javacrumbs.futureconverter.java8guava.FutureConverter; import net.javacrumbs.futureconverter.java8guava.FutureConverter;
import org.dataloader.BatchLoader; import org.dataloader.BatchLoader;
import org.dataloader.DataLoader; import org.dataloader.DataLoader;
Expand All @@ -33,7 +32,6 @@
final class DataLoaderModule extends AbstractModule { final class DataLoaderModule extends AbstractModule {


@Provides @Provides
@RequestScoped
DataLoaderRegistry dataLoaderRegistry(BookServiceGrpc.BookServiceFutureStub bookService) { DataLoaderRegistry dataLoaderRegistry(BookServiceGrpc.BookServiceFutureStub bookService) {


// TODO: Use multibinder to modularize this, or automate this somehow // TODO: Use multibinder to modularize this, or automate this somehow
Expand All @@ -48,14 +46,11 @@ DataLoaderRegistry dataLoaderRegistry(BookServiceGrpc.BookServiceFutureStub book
.build()), .build()),
resp -> resp.getBooksList(), resp -> resp.getBooksList(),
MoreExecutors.directExecutor()); MoreExecutors.directExecutor());
// ServletScopes.transferRequest(() -> ... ); ??
return FutureConverter.toCompletableFuture(listenableFuture); return FutureConverter.toCompletableFuture(listenableFuture);
}; };


DataLoaderRegistry registry = new DataLoaderRegistry(); DataLoaderRegistry registry = new DataLoaderRegistry();

registry.register("books", new DataLoader<>(bookBatchLoader)); registry.register("books", new DataLoader<>(bookBatchLoader));

return registry; return registry;
} }
} }
Expand Up @@ -14,6 +14,8 @@


package com.google.api.graphql.examples.library.graphqlserver; package com.google.api.graphql.examples.library.graphqlserver;


import com.google.api.graphql.examples.library.graphqlserver.client.ClientModule;
import com.google.api.graphql.examples.library.graphqlserver.schema.SchemaModule;
import com.google.api.graphql.rejoiner.SchemaProviderModule; import com.google.api.graphql.rejoiner.SchemaProviderModule;
import com.google.inject.Guice; import com.google.inject.Guice;
import com.google.inject.Injector; import com.google.inject.Injector;
Expand Down Expand Up @@ -41,8 +43,7 @@ public class GraphQlServer {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
Server server = new Server(HTTP_PORT); Server server = new Server(HTTP_PORT);


ServletContextHandler context = ServletContextHandler context = new ServletContextHandler(server, "/", SESSIONS);
new ServletContextHandler(server, "/", SESSIONS);


context.addEventListener( context.addEventListener(
new GuiceServletContextListener() { new GuiceServletContextListener() {
Expand All @@ -58,12 +59,8 @@ protected void configureServlets() {
new DataLoaderModule(), new DataLoaderModule(),
new SchemaProviderModule(), // Part of Rejoiner framework (Provides `@Schema new SchemaProviderModule(), // Part of Rejoiner framework (Provides `@Schema
// GraphQLSchema`) // GraphQLSchema`)
new BookClientModule(), // Configures the Book gRPC client new ClientModule(), // Installs all of the client modules
new ShelfClientModule(), // Configures the Shelf gRPC client new SchemaModule() // Installs all of the schema modules
new BookSchemaModule(), // Creates queries and mutations for the Book service
new ShelfSchemaModule(), // Creates queries and mutations for the Shelf service
new LibrarySchemaModule(), // Joins together Shelf and Book services
new SeedLibrarySchemaModule() // Fills the Shelf and Book services with data
); );
} }
}); });
Expand Down
Expand Up @@ -59,11 +59,12 @@ final class GraphQlServlet extends HttpServlet {
@Override @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {


DataLoaderRegistry dataLoaderRegistry = registryProvider.get();
Instrumentation instrumentation = Instrumentation instrumentation =
new ChainedInstrumentation( new ChainedInstrumentation(
Arrays.asList( Arrays.asList(
GuavaListenableFutureSupport.listenableFutureInstrumentation(), GuavaListenableFutureSupport.listenableFutureInstrumentation(),
new DataLoaderDispatcherInstrumentation(registryProvider.get()), new DataLoaderDispatcherInstrumentation(dataLoaderRegistry),
new TracingInstrumentation())); new TracingInstrumentation()));
GraphQL graphql = GraphQL.newGraphQL(schema).instrumentation(instrumentation).build(); GraphQL graphql = GraphQL.newGraphQL(schema).instrumentation(instrumentation).build();


Expand All @@ -81,13 +82,13 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I
.query(query) .query(query)
.operationName(operationName) .operationName(operationName)
.variables(variables) .variables(variables)
.context(new Object()) .context(dataLoaderRegistry)
.build(); .build();
ExecutionResult executionResult = graphql.execute(executionInput); ExecutionResult executionResult = graphql.execute(executionInput);
resp.setContentType("application/json"); resp.setContentType("application/json");
resp.setStatus(HttpServletResponse.SC_OK); resp.setStatus(HttpServletResponse.SC_OK);
GSON.toJson(executionResult.toSpecification(), resp.getWriter()); GSON.toJson(executionResult.toSpecification(), resp.getWriter());
logger.info("stats: " + registryProvider.get().getStatistics()); logger.info("stats: " + dataLoaderRegistry.getStatistics());
} }


private static Map<String, Object> getVariables(Object variables) { private static Map<String, Object> getVariables(Object variables) {
Expand Down
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.


package com.google.api.graphql.examples.library.graphqlserver; package com.google.api.graphql.examples.library.graphqlserver.client;


import com.google.example.library.book.v1.BookServiceGrpc; import com.google.example.library.book.v1.BookServiceGrpc;
import com.google.inject.AbstractModule; import com.google.inject.AbstractModule;
Expand Down
@@ -0,0 +1,12 @@
package com.google.api.graphql.examples.library.graphqlserver.client;

import com.google.inject.AbstractModule;

/** Installs all of the client modules. */
public final class ClientModule extends AbstractModule {
@Override
protected void configure() {
install(new BookClientModule());
install(new ShelfClientModule());
}
}
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.


package com.google.api.graphql.examples.library.graphqlserver; package com.google.api.graphql.examples.library.graphqlserver.client;


import com.google.example.library.shelf.v1.ShelfServiceGrpc; import com.google.example.library.shelf.v1.ShelfServiceGrpc;
import com.google.inject.AbstractModule; import com.google.inject.AbstractModule;
Expand Down
Expand Up @@ -12,14 +12,15 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.


package com.google.api.graphql.examples.library.graphqlserver; package com.google.api.graphql.examples.library.graphqlserver.schema;


import com.google.api.graphql.rejoiner.Mutation; import com.google.api.graphql.rejoiner.Mutation;
import com.google.api.graphql.rejoiner.Query; import com.google.api.graphql.rejoiner.Query;
import com.google.api.graphql.rejoiner.RelayNode; import com.google.api.graphql.rejoiner.RelayNode;
import com.google.api.graphql.rejoiner.SchemaModule; import com.google.api.graphql.rejoiner.SchemaModule;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import com.google.example.library.book.v1.*; import com.google.example.library.book.v1.*;
import graphql.schema.DataFetchingEnvironment;
import net.javacrumbs.futureconverter.java8guava.FutureConverter; import net.javacrumbs.futureconverter.java8guava.FutureConverter;
import org.dataloader.DataLoaderRegistry; import org.dataloader.DataLoaderRegistry;


Expand All @@ -28,9 +29,13 @@ final class BookSchemaModule extends SchemaModule {


@Query("getBook") @Query("getBook")
@RelayNode @RelayNode
ListenableFuture<Book> getBook(GetBookRequest request, DataLoaderRegistry dataLoaderRegistry) { ListenableFuture<Book> getBook(
GetBookRequest request, DataFetchingEnvironment dataFetchingEnvironment) {
return FutureConverter.toListenableFuture( return FutureConverter.toListenableFuture(
dataLoaderRegistry.<String, Book>getDataLoader("books").load(request.getId())); dataFetchingEnvironment
.<DataLoaderRegistry>getContext()
.<String, Book>getDataLoader("books")
.load(request.getId()));
} }


@Query("listBooks") @Query("listBooks")
Expand Down
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.


package com.google.api.graphql.examples.library.graphqlserver; package com.google.api.graphql.examples.library.graphqlserver.schema;


import com.google.api.graphql.rejoiner.Arg; import com.google.api.graphql.rejoiner.Arg;
import com.google.api.graphql.rejoiner.Mutation; import com.google.api.graphql.rejoiner.Mutation;
Expand All @@ -25,6 +25,7 @@
import com.google.example.library.shelf.v1.GetShelfRequest; import com.google.example.library.shelf.v1.GetShelfRequest;
import com.google.example.library.shelf.v1.Shelf; import com.google.example.library.shelf.v1.Shelf;
import com.google.example.library.shelf.v1.ShelfServiceGrpc; import com.google.example.library.shelf.v1.ShelfServiceGrpc;
import graphql.schema.DataFetchingEnvironment;
import net.javacrumbs.futureconverter.java8guava.FutureConverter; import net.javacrumbs.futureconverter.java8guava.FutureConverter;
import org.dataloader.DataLoaderRegistry; import org.dataloader.DataLoaderRegistry;


Expand All @@ -47,8 +48,11 @@ Book createBookAndAddToShelf(
} }


@SchemaModification(addField = "books", onType = Shelf.class) @SchemaModification(addField = "books", onType = Shelf.class)
ListenableFuture<List<Book>> shelfToBooks(Shelf shelf, DataLoaderRegistry dataLoaderRegistry) { ListenableFuture<List<Book>> shelfToBooks(Shelf shelf, DataFetchingEnvironment environment) {
return FutureConverter.toListenableFuture( return FutureConverter.toListenableFuture(
dataLoaderRegistry.<String, Book>getDataLoader("books").loadMany(shelf.getBookIdsList())); environment
.<DataLoaderRegistry>getContext()
.<String, Book>getDataLoader("books")
.loadMany(shelf.getBookIdsList()));
} }
} }
@@ -0,0 +1,14 @@
package com.google.api.graphql.examples.library.graphqlserver.schema;

import com.google.inject.AbstractModule;

/** Install all of the schema modules. */
public final class SchemaModule extends AbstractModule {
@Override
protected void configure() {
install(new BookSchemaModule()); // Creates queries and mutations for the Book service
install(new ShelfSchemaModule()); // Creates queries and mutations for the Shelf service
install(new LibrarySchemaModule()); // Joins together Shelf and Book services
install(new SeedLibrarySchemaModule()); // Fills the Shelf and Book services with data
}
}
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.


package com.google.api.graphql.examples.library.graphqlserver; package com.google.api.graphql.examples.library.graphqlserver.schema;


import com.google.api.graphql.rejoiner.Mutation; import com.google.api.graphql.rejoiner.Mutation;
import com.google.api.graphql.rejoiner.SchemaModule; import com.google.api.graphql.rejoiner.SchemaModule;
Expand Down
Expand Up @@ -12,20 +12,14 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.


package com.google.api.graphql.examples.library.graphqlserver; package com.google.api.graphql.examples.library.graphqlserver.schema;


import com.google.api.graphql.rejoiner.Mutation; import com.google.api.graphql.rejoiner.Mutation;
import com.google.api.graphql.rejoiner.Query; import com.google.api.graphql.rejoiner.Query;
import com.google.api.graphql.rejoiner.RelayNode; import com.google.api.graphql.rejoiner.RelayNode;
import com.google.api.graphql.rejoiner.SchemaModule; import com.google.api.graphql.rejoiner.SchemaModule;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import com.google.example.library.shelf.v1.CreateShelfRequest; import com.google.example.library.shelf.v1.*;
import com.google.example.library.shelf.v1.GetShelfRequest;
import com.google.example.library.shelf.v1.ListShelvesRequest;
import com.google.example.library.shelf.v1.ListShelvesResponse;
import com.google.example.library.shelf.v1.MergeShelvesRequest;
import com.google.example.library.shelf.v1.Shelf;
import com.google.example.library.shelf.v1.ShelfServiceGrpc;


/** A GraphQL {@link SchemaModule} backed by a gRPC service. */ /** A GraphQL {@link SchemaModule} backed by a gRPC service. */
final class ShelfSchemaModule extends SchemaModule { final class ShelfSchemaModule extends SchemaModule {
Expand Down

0 comments on commit 993c661

Please sign in to comment.