-
Notifications
You must be signed in to change notification settings - Fork 14
/
Routes.kt
76 lines (64 loc) · 2.28 KB
/
Routes.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package com.geowarin.graphql
import graphql.*
import graphql.ExecutionInput.*
import org.springframework.context.annotation.*
import org.springframework.core.io.ClassPathResource
import org.springframework.http.*
import org.springframework.web.reactive.function.server.*
import org.springframework.web.reactive.function.server.ServerResponse.*
import reactor.core.publisher.Mono
import reactor.core.publisher.Mono.*
import java.net.URLDecoder
val GraphQLMediaType = MediaType.parseMediaType("application/GraphQL")
val schema = buildSchema()
@Configuration
class Routes {
@Bean
fun routesFun() = router {
GET("/", serveStatic(ClassPathResource("/graphiql.html")))
(POST("/graphql") or GET("/graphql")).invoke { req: ServerRequest ->
getGraphQLParameters(req)
.flatMap { executeGraphQLQuery(it) }
.flatMap { ok().syncBody(it) }
.switchIfEmpty(badRequest().build())
}
}
}
fun executeGraphQLQuery(graphQLParameters: GraphQLParameters): Mono<ExecutionResult> {
val executionInput = newExecutionInput()
.query(graphQLParameters.query)
.operationName(graphQLParameters.operationName)
.variables(graphQLParameters.variables)
val graphQL = GraphQL
.newGraphQL(schema)
.build()
return fromFuture(graphQL.executeAsync(executionInput))
}
fun getGraphQLParameters(req: ServerRequest): Mono<GraphQLParameters> = when {
req.queryParam("query").isPresent -> graphQLParametersFromRequestParameters(req)
req.method() == HttpMethod.POST -> parsePostRequest(req)
else -> empty()
}
fun parsePostRequest(req: ServerRequest) = when {
req.contentTypeIs(GraphQLMediaType) -> req.withBody { GraphQLParameters(query = it) }
else -> req.withBody { readJson<GraphQLParameters>(it) }
}
fun graphQLParametersFromRequestParameters(req: ServerRequest) =
just(
GraphQLParameters(
query = req.queryParam("query").get(),
operationName = req.queryParam("operationName").orElseGet { null },
variables = getVariables(req)
)
)
fun getVariables(req: ServerRequest): Map<String, Any>? {
return req.queryParam("variables")
.map { URLDecoder.decode(it, "UTF-8") }
.map { readJsonMap(it) }
.orElseGet { null }
}
data class GraphQLParameters(
val query: String,
val operationName: String? = null,
val variables: Map<String, Any>? = null
)