Refactor project structure

This commit refactors the project structure to regroup GraphQL web
support under the spring-graphql-web module, and move all the Spring
Boot support classes under a single graphql-spring-boot-starter one.

Right now, the starter module contains everything: classes for MVC,
WebFlux and Actuator support as well as required dependencies. We will
change that in the future.
This commit is contained in:
Brian Clozel
2021-01-05 16:19:48 +01:00
parent 3e8027a0ca
commit 633ee1a1b5
32 changed files with 214 additions and 59 deletions

View File

@@ -11,12 +11,12 @@ This project is tested against Spring Boot 2.4+, but should work on 2.3 as well.
You can start by creating a project on https://start.spring.io and select the `spring-boot-starter-web` or `spring-boot-starter-webflux` starter,
depending on the type of web application you'd like to build. Once the project is generated, you can manually add the
`org.springframework.experimental:spring-graphql-web` dependency.
`org.springframework.experimental:graphql-spring-boot-starter` dependency.
`build.gradle` snippet:
```groovy
dependencies {
implementation 'org.springframework.experimental:spring-graphql-web:0.1.0-SNAPSHOT'
implementation 'org.springframework.experimental:graphql-spring-boot-starter:0.1.0-SNAPSHOT'
// Spring Web MVC starter
implementation 'org.springframework.boot:spring-boot-starter-web'
@@ -38,7 +38,7 @@ repositories {
<dependencies>
<dependency>
<groupId>org.springframework.experimental</groupId>
<artifactId>spring-graphql-web</artifactId>
<artifactId>graphql-spring-boot-starter</artifactId>
<version>0.1.0-SNAPSHOT</version>
</dependency>
@@ -142,14 +142,15 @@ management.endpoints.web.exposure.include=health,metrics,info
You can then check those metrics at `http://localhost:8080/actuator/metrics/graphql.query`.
## Sample application
## Sample applications
This repository contains a sample application that the team is using to test new features and ideas.
This repository contains sample applications that the team is using to test new features and ideas.
You can run it by cloning this repository and typing on the command line:
You can run them by cloning this repository and typing on the command line:
```shell script
$ ./gradlew :graphql-sample:bootRun
$ ./gradlew :samples:webmvc-http:bootRun
$ ./gradlew :samples:webflux-websocket:bootRun
```

View File

@@ -0,0 +1,66 @@
import org.springframework.boot.gradle.plugin.SpringBootPlugin
plugins {
id 'org.springframework.boot' version '2.4.1' apply false
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id 'java-library'
id 'maven'
}
description = "GraphQL Spring Boot Starter"
sourceCompatibility = 1.8
targetCompatibility = 1.8
configurations {
apt
}
dependencyManagement {
imports {
mavenBom SpringBootPlugin.BOM_COORDINATES
}
generatedPomCustomization {
enabled = false
}
}
dependencies {
api project(':spring-graphql-web')
api 'com.graphql-java:graphql-java:15.0'
// Reactor is required as it's part of the interception model
api 'io.projectreactor:reactor-core'
api 'org.springframework:spring-context'
api 'org.springframework.boot:spring-boot-starter'
compileOnly 'org.springframework:spring-webflux'
compileOnly 'javax.servlet:javax.servlet-api'
compileOnly 'org.springframework:spring-webmvc'
compileOnly 'io.micrometer:micrometer-core'
compileOnly 'org.springframework.boot:spring-boot-actuator-autoconfigure'
apt 'javax.annotation:javax.annotation-api:1.3.2'
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
annotationProcessor 'org.springframework.boot:spring-boot-autoconfigure-processor'
testImplementation 'com.fasterxml.jackson.core:jackson-databind'
testImplementation 'org.springframework:spring-webflux'
testImplementation 'org.springframework:spring-webmvc'
testImplementation 'io.projectreactor:reactor-test'
testImplementation 'javax.servlet:javax.servlet-api'
testImplementation 'org.springframework.boot:spring-boot-actuator-autoconfigure'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
compileJava {
options.annotationProcessorPath = configurations.apt
}
test {
useJUnitPlatform()
testLogging {
events "passed", "skipped", "failed"
}
}
apply from: "${rootDir}/gradle/publishing.gradle"

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.graphql;
package org.springframework.graphql.boot;
import java.io.IOException;
import java.util.List;

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.graphql;
package org.springframework.graphql.boot;
import java.time.Duration;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.boot.graphql;
package org.springframework.graphql.boot;
import org.springframework.core.io.Resource;

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.graphql;
package org.springframework.graphql.boot;
import graphql.schema.idl.RuntimeWiring;

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.graphql;
package org.springframework.graphql.boot;
import java.util.Collections;

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.graphql;
package org.springframework.graphql.boot;
import java.util.Collections;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.boot.actuate.metrics.graphql;
package org.springframework.graphql.boot.actuate.metrics;
import graphql.ErrorClassification;
import graphql.ErrorType;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.boot.actuate.metrics.graphql;
package org.springframework.graphql.boot.actuate.metrics;
import io.micrometer.core.instrument.MeterRegistry;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.boot.actuate.metrics.graphql;
package org.springframework.graphql.boot.actuate.metrics;
import graphql.ExecutionResult;
import graphql.execution.instrumentation.InstrumentationContext;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.boot.actuate.metrics.graphql;
package org.springframework.graphql.boot.actuate.metrics;
import org.springframework.boot.actuate.autoconfigure.metrics.AutoTimeProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.boot.actuate.metrics.graphql;
package org.springframework.graphql.boot.actuate.metrics;
import graphql.ExecutionResult;
import graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters;

View File

@@ -15,7 +15,7 @@
*/
@NonNullApi
@NonNullFields
package org.springframework.boot.graphql;
package org.springframework.graphql.boot;
import org.springframework.lang.NonNullApi;
import org.springframework.lang.NonNullFields;

View File

@@ -0,0 +1 @@
restart.include.graphqljava=graphql-java[\\w-]+\.jar

View File

@@ -0,0 +1,5 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.graphql.boot.actuate.metrics.GraphQLMetricsAutoConfiguration,\
org.springframework.graphql.boot.GraphQLAutoConfiguration,\
org.springframework.graphql.boot.WebFluxGraphQLAutoConfiguration,\
org.springframework.graphql.boot.WebMvcGraphQLAutoConfiguration

View File

@@ -0,0 +1,54 @@
package org.springframework.graphql.boot;
public class Book {
String id;
String name;
int pageCount;
String author;
public Book() {
}
public Book(String id, String name, int pageCount, String author) {
this.id = id;
this.name = name;
this.pageCount = pageCount;
this.author = author;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPageCount() {
return pageCount;
}
public void setPageCount(int pageCount) {
this.pageCount = pageCount;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.boot.graphql;
package org.springframework.graphql.boot;
import graphql.GraphQL;
import graphql.schema.GraphQLObjectType;

View File

@@ -0,0 +1,30 @@
package org.springframework.graphql.boot;
import java.util.Arrays;
import java.util.List;
import graphql.schema.DataFetcher;
import reactor.core.publisher.Flux;
public class GraphQLDataFetchers {
private static List<Book> books = Arrays.asList(
new Book("book-1", "GraphQL for beginners", 100, "John GraphQL"),
new Book("book-2", "Harry Potter and the Philosopher's Stone", 223, "Joanne Rowling"),
new Book("book-3", "Moby Dick", 635, "Moby Dick"),
new Book("book-3", "Moby Dick", 635, "Moby Dick"));
public static DataFetcher getBookByIdDataFetcher() {
return environment -> books.stream()
.filter(book -> book.getId().equals(environment.getArgument("id")))
.findFirst()
.orElse(null);
}
public static DataFetcher getBooksOnSale() {
return environment -> Flux.fromIterable(books)
.filter(book -> book.getPageCount() >= (int) environment.getArgument("minPages"));
}
}

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.graphql;
package org.springframework.graphql.boot;
import java.util.Collections;
import java.util.function.Consumer;
@@ -30,7 +30,6 @@ import org.springframework.boot.test.context.runner.ReactiveWebApplicationContex
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.graphql.GraphQLDataFetchers;
import org.springframework.http.MediaType;
import org.springframework.test.web.reactive.server.WebTestClient;

View File

@@ -1,4 +1,4 @@
package org.springframework.boot.graphql;
package org.springframework.graphql.boot;
import org.junit.jupiter.api.Test;
@@ -11,13 +11,10 @@ import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguratio
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.graphql.GraphQLDataFetchers;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import static graphql.schema.idl.TypeRuntimeWiring.newTypeWiring;

View File

@@ -0,0 +1,14 @@
type Query {
bookById(id: ID): Book
}
type Book {
id: ID
name: String
pageCount: Int
author: String
}
type Subscription {
bookSearch(minPages:Int) : Book!
}

View File

@@ -1,5 +1,5 @@
plugins {
id 'org.springframework.boot' version '2.4.0-SNAPSHOT'
id 'org.springframework.boot' version '2.4.1'
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id 'java'
}
@@ -9,7 +9,7 @@ description = "GraphQL over WebSocket sample"
sourceCompatibility = '1.8'
dependencies {
implementation project(':spring-graphql-web')
implementation project(':graphql-spring-boot-starter')
implementation 'org.springframework.boot:spring-boot-starter-webflux'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
developmentOnly 'org.springframework.boot:spring-boot-devtools'

View File

@@ -5,7 +5,7 @@ import java.time.Duration;
import graphql.schema.idl.RuntimeWiring;
import reactor.core.publisher.Flux;
import org.springframework.boot.graphql.RuntimeWiringCustomizer;
import org.springframework.graphql.boot.RuntimeWiringCustomizer;
import org.springframework.stereotype.Component;
@Component

View File

@@ -1,5 +1,5 @@
plugins {
id 'org.springframework.boot' version '2.4.0-SNAPSHOT'
id 'org.springframework.boot' version '2.4.1'
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id 'java'
}
@@ -9,7 +9,7 @@ description = "GraphQL sample application"
sourceCompatibility = '1.8'
dependencies {
implementation project(':spring-graphql-web')
implementation project(':graphql-spring-boot-starter')
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-hateoas'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'

View File

@@ -2,7 +2,7 @@ package io.spring.sample.graphql.project;
import graphql.schema.idl.RuntimeWiring;
import org.springframework.boot.graphql.RuntimeWiringCustomizer;
import org.springframework.graphql.boot.RuntimeWiringCustomizer;
import org.springframework.stereotype.Component;
@Component

View File

@@ -2,7 +2,7 @@ package io.spring.sample.graphql.repository;
import graphql.schema.idl.RuntimeWiring;
import org.springframework.boot.graphql.RuntimeWiringCustomizer;
import org.springframework.graphql.boot.RuntimeWiringCustomizer;
import org.springframework.stereotype.Component;
@Component

View File

@@ -14,6 +14,4 @@ pluginManagement {
}
rootProject.name = 'spring-graphql'
include 'spring-graphql-web'
include 'samples:webmvc-http'
include 'samples:webflux-websocket'
include 'spring-graphql-web', 'graphql-spring-boot-starter', 'samples:webmvc-http', 'samples:webflux-websocket'

View File

@@ -1,7 +1,5 @@
import org.springframework.boot.gradle.plugin.SpringBootPlugin
plugins {
id 'org.springframework.boot' version '2.4.1' apply false
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id 'java-library'
id 'maven'
@@ -13,7 +11,9 @@ targetCompatibility = 1.8
dependencyManagement {
imports {
mavenBom SpringBootPlugin.BOM_COORDINATES
mavenBom "com.fasterxml.jackson:jackson-bom:2.12.0"
mavenBom "io.projectreactor:reactor-bom:2020.0.2"
mavenBom "org.springframework:spring-framework-bom:5.3.2"
}
generatedPomCustomization {
enabled = false
@@ -24,28 +24,24 @@ dependencies {
api 'com.graphql-java:graphql-java:15.0'
// Reactor is required as it's part of the interception model
api 'io.projectreactor:reactor-core'
// auto-configurations should be moved to the spring-boot project
api 'org.springframework.boot:spring-boot-autoconfigure'
api 'org.springframework:spring-context'
compileOnly 'org.springframework:spring-context'
compileOnly "javax.annotation:javax.annotation-api:1.3.2"
compileOnly 'org.springframework:spring-webflux'
compileOnly 'org.springframework:spring-webmvc'
compileOnly 'javax.servlet:javax.servlet-api'
compileOnly 'io.micrometer:micrometer-core'
compileOnly 'org.springframework.boot:spring-boot-actuator-autoconfigure'
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
annotationProcessor 'org.springframework.boot:spring-boot-autoconfigure-processor'
compileOnly 'javax.servlet:javax.servlet-api:4.0.1'
testImplementation 'com.fasterxml.jackson.core:jackson-databind'
testImplementation 'org.springframework:spring-webflux'
testImplementation 'org.springframework:spring-webmvc'
testImplementation 'io.projectreactor:reactor-test'
testImplementation 'javax.servlet:javax.servlet-api'
testImplementation 'org.springframework.boot:spring-boot-actuator-autoconfigure'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'javax.servlet:javax.servlet-api:4.0.1'
testImplementation 'com.jayway.jsonpath:json-path:2.4.0'
testImplementation 'org.assertj:assertj-core:3.18.1'
testImplementation 'org.junit.jupiter:junit-jupiter:5.7.0'
testImplementation 'org.skyscreamer:jsonassert:1.5.0'
testImplementation 'org.springframework:spring-test'
}
test {

View File

@@ -1 +0,0 @@
restart.include.graphql-java=graphql-java.*\.jar

View File

@@ -1,5 +0,0 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.actuate.metrics.graphql.GraphQLMetricsAutoConfiguration,\
org.springframework.boot.graphql.GraphQLAutoConfiguration,\
org.springframework.boot.graphql.WebFluxGraphQLAutoConfiguration,\
org.springframework.boot.graphql.WebMvcGraphQLAutoConfiguration