Coder Social home page Coder Social logo

williamkwao / graphql-java-servlet Goto Github PK

View Code? Open in Web Editor NEW

This project forked from graphql-java-kickstart/graphql-java-servlet

0.0 2.0 0.0 814 KB

Servlet endpoint for GraphQL Java

Home Page: https://www.graphql-java-kickstart.com/servlet/

License: Other

Java 71.83% Groovy 27.90% Shell 0.27%

graphql-java-servlet's Introduction

Build Status Maven Central Chat on Gitter

GraphQL Servlet

Implementation of GraphQL Java Servlet including support for Relay.js, Apollo and OSGi out of the box. This project wraps the Java implementation of GraphQL provided by GraphQL Java. See GraphQL Java documentation for more in depth details regarding GraphQL Java itself.

We try to stay up to date with GraphQL Java as much as possible. The current version supports GraphQL Java 11.0.

This project requires at least Java 8.

Quick start

See Getting started for more detailed instructions.

To add graphql-java-servlet to your project and get started quickly, do the following.

Build with Gradle

Make sure mavenCentral is amongst your repositories:

repositories {
    mavenCentral()
}

Add the graphql-java-servlet dependency:

dependencies {
    compile 'com.graphql-java-kickstart:graphql-java-servlet:8.0.0'
}

Build with Maven

Add the graphql-java-servlet dependency:

<dependency>
  <groupId>com.graphql-java-kickstart</groupId>
  <artifactId>graphql-java-servlet</artifactId>
  <version>8.0.0</version>
</dependency>

Create a Servlet class

Creating the Servlet class requires various parameters to be provided at the moment. We're working on simplifying this, to make it easier to get started. For now, take a look at Create a Servlet class to see what's needed to create a Servlet with a schema.

Using the latest development build

Snapshot versions of the current master branch are available on JFrog. Check the next snapshot version in gradle.properties.

Build with Gradle

Add the Snapshot repository:

repositories {
    mavenCentral()
    maven { url "http://oss.jfrog.org/artifactory/oss-snapshot-local" }
}

Build with Maven

Add the Snapshot repository:

<repositories>
  <repository>
    <id>oss-snapshot-local</id>
    <name>jfrog</name>
    <url>http://oss.jfrog.org/artifactory/oss-snapshot-local</url>
    <snapshots>
      <enabled>true</enabled>
      <updatePolicy>always</updatePolicy>
    </snapshots>
  </repository>
</repositories>

Usage

The servlet supports the following request formats:

  • GET request to ../schema.json: Get the result of an introspection query.
  • GET request with query parameters (query only, no mutation):
    • query
    • operationName (optional)
    • variables (optional)
  • POST body JSON object with fields:
    • query
    • operationName (optional)
    • variables (optional)
  • POST multipart part named "graphql" containing JSON object with fields:
    • query
    • operationName (optional)
    • variables (optional)
  • POST multipart parts named "query", "operationName" (optional), and "variables" (optional)
  • POST with Content Type "application/graphql" will treat the HTTP POST body contents as the GraphQL query string

Servlet Listeners

You can also add servlet listeners to an existing servlet. These listeners provide hooks into query execution (before, success, failure, and finally) and servlet execution (before, success, error, and finally):

servlet.addListener(new GraphQLServletListener() {
    @Override
    GraphQLServletListener.RequestCallback onRequest(HttpServletRequest request, HttpServletResponse response) {

        return new GraphQLServletListener.RequestCallback() {
            @Override
            void onSuccess(HttpServletRequest request, HttpServletResponse response) {

            }

            @Override
            void onError(HttpServletRequest request, HttpServletResponse response, Throwable throwable) {

            }

            @Override
            void onFinally(HttpServletRequest request, HttpServletResponse response) {

            }
        }
    }

    @Override
    GraphQLServletListener.OperationCallback onOperation(GraphQLContext context, String operationName, String query, Map<String, Object> variables) {

        return new GraphQLServletListener.OperationCallback() {
            @Override
            void onSuccess(GraphQLContext context, String operationName, String query, Map<String, Object> variables, Object data) {

            }

            @Override
            void onError(GraphQLContext context, String operationName, String query, Map<String, Object> variables, Object data, List<GraphQLError> errors) {

            }

            @Override
            void onFinally(GraphQLContext context, String operationName, String query, Map<String, Object> variables, Object data) {

            }
        }
    }
})

Relay.js support

Relay.js support is provided by the EnhancedExecutionStrategy of graphql-java-annotations. You MUST pass this execution strategy to the servlet for Relay.js support.

This is the default execution strategy for the OsgiGraphQLHttpServlet, and must be added as a dependency when using that servlet.

Apollo support

Query batching is supported, no configuration required.

Spring Framework support

To use the servlet with Spring Framework, either use the Spring Boot starter or simply define a ServletRegistrationBean in a web app:

@Bean
ServletRegistrationBean graphQLServletRegistrationBean(GraphQLSchema schema, ExecutionStrategy executionStrategy, List<GraphQLOperationListener> operationListeners) {
    return new ServletRegistrationBean(new SimpleGraphQLServlet(schema, executionStrategy, operationListeners), "/graphql");
}

OSGI support

The OsgiGraphQLHttpServlet uses a "provider" model to supply the servlet with the required objects:

Examples

You can now find some example on how to use graphql-java-servlet.

OSGi Examples

Requirements

The OSGi examples use Maven as a build tool because it requires plugins that are not (yet) available for Gradle. Therefore you will need Maven 3.2+.

Building & running the OSGi examples

You can build the OSGi examples sub-projects by simply executing the following command from the examples/osgi directory:

mvn clean install

This will generate a complete Apache Karaf distribution in the following files:

 examples/osgi/apache-karaf-package/target/graphql-java-servlet-osgi-examples-apache-karaf-package-VERSION.tar.gz(.zip)

You can simply uncompress this file and launch the OSGi server using the command from the uncompressed directory:

bin/karaf

You should then be able to access the GraphQL endpoint at the following URL once the server is started:

http://localhost:8181/graphql/schema.json

If you see the JSON result of an introspection query, then all is ok. If not, check the data/log/karaf.log file for any errors.

We also provide a script file to do all of the building and running at once (only for Linux / MacOS ):

./buildAndRun.sh

Deploying inside Apache Karaf server

You can use the graphql-java-servlet as part of an Apache Karaf feature, as you can see in the example project here:

And here is a sample src/main/feature/feature.xml file to add some dependencies on other features:

Example GraphQL provider implementation

Here's an example of a GraphQL provider that implements three interfaces at the same time.

Context and DataLoader settings

It is possible to create context, and consequently dataloaders, in both a request scope and a per query scope by customizing GraphQLContextBuilder and selecting the appropriate ContextSetting with the provided GraphQLConfiguration. A new DataLoaderRegistry should be created in each call to the GraphQLContextBuilder, and the servlet will call the builder at the appropriate times. For eg:

public class CustomGraphQLContextBuilder implements GraphQLContextBuilder {

    private final DataLoader userDataLoader;

    public CustomGraphQLContextBuilder(DataLoader userDataLoader) {
        this.userDataLoader = userDataLoader;
    }

    @Override
    public GraphQLContext build(HttpServletRequest req) {
        return new GraphQLContext(buildDataLoaderRegistry());
    }

    @Override
    public GraphQLContext build() {
        return new GraphQLContext(buildDataLoaderRegistry());
    }

    @Override
    public GraphQLContext build(HandshakeRequest request) {
        return new GraphQLContext(buildDataLoaderRegistry());
    }

    private DataLoaderRegistry buildDataLoaderRegistry() {
        DataLoaderRegistry dataLoaderRegistry = new DataLoaderRegistry();
        dataLoaderRegistry.register("userDataLoader", userDataLoader);
        return dataLoaderRegistry;
    }
}

It is then possible to access the DataLoader in the resolvers by accessing the [DataLoaderRegistry] from context. For eg:

public CompletableFuture<String> getEmailAddress(User user, DataFetchingEnvironment dfe) { // User is the graphQL type
        final DataLoader<String, UserDetail> userDataloader =
               dfe.getContext().getDataLoaderRegistry().get().getDataLoader("userDataLoader"); // UserDetail is the data that is loaded

        return userDataloader.load(User.getName())
                .thenApply(userDetail -> userDetail != null ? userDetail.getEmailAddress() : null);
    }

If per request is selected this will cause all queries within the http request, if using a batch, to share dataloader caches and batch together load calls as efficently as possible. The dataloaders are dispatched using instrumentation and the correct instrumentation will be selected according to the ContextSetting. The default context setting in GraphQLConfiguration is per query.

Two additional context settings are provided, one for each of the previous settings but without the addition of the Dataloader dispatching instrumentation. This is useful for those not using Dataloaders or wanting to supply their own dispatching instrumentation though the instrumentation supplier within the GraphQLQueryInvoker.

graphql-java-servlet's People

Contributors

oliemansm avatar apottere avatar yrashk avatar jmccaull avatar sergehuber avatar jplock avatar osi avatar denvned avatar sammyhk avatar mlvandijk avatar ronald-d-rogers avatar wleroux avatar tomqwpl avatar ma2gedev avatar bsara avatar zdtaylor86 avatar nrouge avatar jnutting512 avatar fnovoa10 avatar vojtechhabarta avatar shariqislam786 avatar ryanlewis avatar ryangardner avatar pcarrier avatar karlhorky avatar jessthrysoee avatar jbonofre avatar metacosm avatar briancullen avatar alexdanielyan avatar

Watchers

James Cloos avatar William Kwao avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.