Skip to content

Commit 04e29e4

Browse files
author
Robert Wiesner
authored
Use spring-graphql (#140)
1 parent 188b8fa commit 04e29e4

File tree

14 files changed

+91
-73
lines changed

14 files changed

+91
-73
lines changed

.graphqlconfig

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"name": "Spring GraphQL Schema",
3+
"schemaPath": "src/main/resources/graphql/schema.graphqls",
4+
"extensions": {}
5+
}

README.md

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ Simple Spring WebFlux Project (see [Help.md](HELP.md)) with:
44

55
* Classic Annotation Based REST
66
* WebFlux.Fn / coRouter REST
7-
* [graphql-kotlin](https://github.com/ExpediaGroup/graphql-kotlin) GraphQL ([Why?](https://opensource.expediagroup.com/graphql-kotlin/docs/framework-comparison))
7+
- Moved from [graphql-kotlin](https://github.com/ExpediaGroup/graphql-kotlin) to [spring-graphql](https://docs.spring.io/spring-graphql/docs/current/reference/html)
8+
- For [graphql-kotlin](https://opensource.expediagroup.com/graphql-kotlin/docs/framework-comparison) impl. with Spring Boot 2.x.x use [#811dcc2](https://github.com/rowi1de/graphql-reactive/commit/c88c63b40584c5e0ef3d64d6ee4a108bd5608aa1)
89

910
## Kotlin
1011

@@ -25,26 +26,26 @@ This project uses [ktlint](https://ktlint.github.io/)
2526
### Graphql
2627
* graphql Endpoints
2728
* [graphql](http://localhost:8082/graphql)
28-
* [playground](http://localhost:8082/playground)
29-
* [sdl](http://localhost:8082/sdl)
30-
* [subscription](http://localhost:8082/subscription)
29+
* [graphiql](http://localhost:8082/graphiql)
30+
* [subscription](http://localhost:8082/subscriptions)
3131

32-
Use [playground](http://localhost:8082/playground) to execute queries and browse schema
32+
Use [graphiql](http://localhost:8082/graphiql) to execute queries and browse schema
3333
or [js-graphql](https://plugins.jetbrains.com/plugin/8097-js-graphql)
3434

3535
#### Query
3636
```graphql
3737
#default value
38-
query helloWorld{
38+
query default {
3939
hello {
4040
greeting
41+
time
4142
}
4243
}
43-
44-
# with paramter
45-
query helloRob{
46-
hello(name:"Rob") {
44+
#with input
45+
query rob {
46+
hello(name: "Rob") {
4747
greeting
48+
time
4849
}
4950
}
5051
```

build.gradle.kts

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ plugins {
55
id("io.spring.dependency-management") version "1.1.0"
66
kotlin("jvm") version "1.7.22"
77
kotlin("plugin.spring") version "1.7.22"
8-
kotlin("kapt") version "1.7.22"
98
}
109

1110
group = "de.rowi1de.graphql"
@@ -27,8 +26,6 @@ dependencies {
2726
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
2827
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor")
2928

30-
// GraphQL
31-
implementation("com.expediagroup:graphql-kotlin-spring-server:6.3.0")
3229

3330
// Rest
3431
implementation("org.springdoc:springdoc-openapi-kotlin:1.6.13") {
@@ -38,13 +35,23 @@ dependencies {
3835
exclude("io.github.classgraph", "classgraph")
3936
}
4037

38+
// GraphQL
39+
implementation("org.springframework.boot:spring-boot-starter-graphql")
40+
4141
developmentOnly("org.springframework.boot:spring-boot-devtools")
42+
annotationProcessor("org.springframework.boot:spring-boot-configuration-processor")
43+
4244
testImplementation("org.springframework.boot:spring-boot-starter-test")
4345
testImplementation("io.projectreactor:reactor-test")
4446
testImplementation("org.springframework.security:spring-security-test")
45-
kapt("org.springframework.boot:spring-boot-configuration-processor")
46-
}
47+
testImplementation("org.springframework.graphql:spring-graphql-test")
4748

49+
}
50+
configurations {
51+
compileOnly {
52+
extendsFrom(configurations.annotationProcessor.get())
53+
}
54+
}
4855
tasks.withType<KotlinCompile> {
4956
kotlinOptions {
5057
freeCompilerArgs = listOf(

graphql/.graphqlconfig

Lines changed: 0 additions & 15 deletions
This file was deleted.
Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
package de.rowi1de.reactive.graphql.model
22

3-
import com.expediagroup.graphql.generator.annotations.GraphQLDescription
3+
import org.springframework.graphql.data.method.annotation.SchemaMapping
44
import java.time.ZonedDateTime
55

6-
@GraphQLDescription("Simple World")
6+
7+
78
data class HelloGraphql(
89

910
private val name: String
1011
) {
11-
@GraphQLDescription("Say Hello")
1212
val greeting: String
1313
get() = "Hello $name!"
1414

15-
@GraphQLDescription("Time of greeting")
1615
val time: String
1716
get() = ZonedDateTime.now().toString()
1817
}
Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
package de.rowi1de.reactive.graphql.mutation.employees
22

3-
import com.expediagroup.graphql.server.operations.Mutation
43
import de.rowi1de.reactive.graphql.model.employees.Employee
54
import de.rowi1de.reactive.graphql.model.employees.NewEmployee
65
import de.rowi1de.reactive.service.employees.EmployeeService
7-
import org.springframework.stereotype.Component
6+
import org.springframework.graphql.data.method.annotation.MutationMapping
7+
import org.springframework.stereotype.Controller
88

9-
@Component
10-
class EmployeesMutation(private val service: EmployeeService) : Mutation {
9+
@Controller
10+
class EmployeesMutation(private val service: EmployeeService) {
1111

12+
@MutationMapping
1213
suspend fun newEmployee(newEmployee: NewEmployee): Employee = service.addEmployee(newEmployee)
1314
}

src/main/kotlin/de/rowi1de/reactive/graphql/query/BrokenQuery.kt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
package de.rowi1de.reactive.graphql.query
22

3-
import com.expediagroup.graphql.server.operations.Query
43
import de.rowi1de.reactive.graphql.model.HelloGraphql
54
import graphql.GraphqlErrorBuilder.newError
65
import graphql.execution.DataFetcherResult
76
import graphql.schema.DataFetchingEnvironment
8-
import org.springframework.stereotype.Component
7+
import org.springframework.graphql.data.method.annotation.QueryMapping
8+
import org.springframework.stereotype.Controller
99

10-
@Component
11-
class BrokenQuery : Query {
10+
@Controller
11+
class BrokenQuery {
1212

13+
@QueryMapping
1314
suspend fun broken(): HelloGraphql = TODO("I told you")
1415

16+
@QueryMapping
1517
suspend fun partialBroken(env: DataFetchingEnvironment): DataFetcherResult<HelloGraphql> =
1618
DataFetcherResult.newResult<HelloGraphql>()
1719
.data(HelloGraphql("Broken"))
Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
package de.rowi1de.reactive.graphql.query
22

3-
import com.expediagroup.graphql.generator.annotations.GraphQLDescription
4-
import com.expediagroup.graphql.server.operations.Query
53
import de.rowi1de.reactive.graphql.model.HelloGraphql
6-
import org.springframework.stereotype.Component
4+
import org.springframework.graphql.data.method.annotation.Argument
5+
import org.springframework.graphql.data.method.annotation.QueryMapping
6+
import org.springframework.stereotype.Controller
77

8-
@Component
9-
class HelloQuery : Query {
8+
@Controller
9+
class HelloQuery {
1010

11-
@GraphQLDescription("Simple Hello World Query")
11+
@QueryMapping
1212
suspend fun hello(
13-
@GraphQLDescription("Who should we greet?") name: String? = null
13+
@Argument name: String? = null
1414
): HelloGraphql = HelloGraphql(name ?: "World")
1515
}
Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
package de.rowi1de.reactive.graphql.query.employees
22

3-
import com.expediagroup.graphql.server.operations.Query
43
import de.rowi1de.reactive.graphql.model.employees.Employees
54
import de.rowi1de.reactive.graphql.model.employees.Teams
65
import de.rowi1de.reactive.service.employees.EmployeeService
7-
import org.springframework.stereotype.Component
6+
import org.springframework.graphql.data.method.annotation.QueryMapping
7+
import org.springframework.stereotype.Controller
88

9-
@Component
10-
class EmployeesQuery(private val service: EmployeeService) : Query {
9+
@Controller
10+
class EmployeesQuery(private val service: EmployeeService) {
1111

12+
@QueryMapping
1213
suspend fun employees(): Employees = Employees(service.getEmployees())
1314

15+
@QueryMapping
1416
suspend fun teams(): Teams = Teams(service.getTeams())
1517
}
Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
package de.rowi1de.reactive.graphql.subscription
22

3-
import com.expediagroup.graphql.generator.annotations.GraphQLDescription
4-
import com.expediagroup.graphql.server.operations.Subscription
53
import de.rowi1de.reactive.graphql.model.HelloGraphql
6-
import org.springframework.stereotype.Component
4+
import org.springframework.graphql.data.method.annotation.SubscriptionMapping
5+
import org.springframework.stereotype.Controller
76
import reactor.core.publisher.Flux
87
import java.time.Duration
98

10-
@Component
11-
class HelloSubscription : Subscription {
12-
@GraphQLDescription("Greet every second")
9+
@Controller
10+
class HelloSubscription {
11+
@SubscriptionMapping
1312
suspend fun hello(name: String): Flux<HelloGraphql> = Flux.interval(Duration.ofSeconds(1))
1413
.map { HelloGraphql("$name $it") }
1514
}
Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
package de.rowi1de.reactive.graphql.subscription.employee
22

3-
import com.expediagroup.graphql.server.operations.Subscription
43
import de.rowi1de.reactive.graphql.model.employees.Employee
54
import de.rowi1de.reactive.service.employees.EmployeeService
65
import kotlinx.coroutines.reactor.asFlux
7-
import org.springframework.stereotype.Component
6+
import org.springframework.graphql.data.method.annotation.SubscriptionMapping
7+
import org.springframework.stereotype.Controller
88
import reactor.core.publisher.Flux
99

10-
@Component
11-
class EmployeeSubscription(private val service: EmployeeService) : Subscription {
10+
@Controller
11+
class EmployeeSubscription(private val service: EmployeeService) {
12+
@SubscriptionMapping
1213
suspend fun employees(): Flux<Employee> = service.employees().asFlux()
1314
}

src/main/kotlin/de/rowi1de/reactive/security/SecurityConfig.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@ package de.rowi1de.reactive.security
22

33
import org.springframework.context.annotation.Bean
44
import org.springframework.context.annotation.Configuration
5+
import org.springframework.security.config.annotation.method.configuration.EnableReactiveMethodSecurity
56
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity
67
import org.springframework.security.config.web.server.ServerHttpSecurity
78
import org.springframework.security.web.server.SecurityWebFilterChain
89

9-
@EnableWebFluxSecurity
1010
@Configuration
11+
@EnableWebFluxSecurity
12+
@EnableReactiveMethodSecurity
1113
class SecurityConfig {
1214

1315
@Bean
@@ -19,7 +21,7 @@ class SecurityConfig {
1921
// graphql
2022
.pathMatchers(
2123
"/graphql", // single graphql POST Endpoint for query / mutations / introspection
22-
"/playground", // playground
24+
"/graphiql", // playground
2325
"/sdl", // schema
2426
"/subscriptions" // apollo compatible websocket subscription
2527
)

src/main/resources/application.yaml

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,6 @@
11
server:
22
port: 8082
33

4-
graphql:
5-
packages:
6-
- "de.rowi1de.reactive.graphql"
7-
subscriptions:
8-
endpoint: subscriptions
9-
keep-alive-interval: 1000
10-
114
springdoc:
125
api-docs:
136
path: "/api-docs"
@@ -30,4 +23,17 @@ management:
3023
endpoints:
3124
web:
3225
exposure:
33-
include: metrics,health,prometheus,info,httptrace
26+
include: metrics,health,prometheus,info,httptrace
27+
28+
29+
spring:
30+
graphql:
31+
websocket:
32+
path: /subscriptions
33+
graphiql:
34+
enabled: true
35+
path: /graphiql
36+
security:
37+
user:
38+
name: user
39+
password: password
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
type Query {
2+
hello(name: String): HelloGraphql!
3+
}
4+
5+
type HelloGraphql{
6+
greeting: String!
7+
time: String!
8+
}

0 commit comments

Comments
 (0)