Skip to content

Commit 938d056

Browse files
committed
refactor(graphql): move data fetcher to extra file
- optimize imports
1 parent 984808f commit 938d056

File tree

2 files changed

+130
-118
lines changed

2 files changed

+130
-118
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
package app.ryss.gateway.gql
2+
3+
import app.ryss.gateway.core.GatewayService
4+
import app.ryss.gateway.ratelimits.RateLimiter
5+
import graphql.GraphqlErrorBuilder
6+
import graphql.execution.DataFetcherResult
7+
import graphql.schema.DataFetcher
8+
import graphql.schema.DataFetchingEnvironment
9+
import io.ktor.application.ApplicationCall
10+
import io.ktor.application.call
11+
import io.ktor.util.pipeline.PipelineContext
12+
import kotlinx.coroutines.runBlocking
13+
import java.time.temporal.ChronoUnit
14+
15+
16+
/**
17+
* Creates an [RatelimitedDataFetcher] with [maxRequests] and [name].
18+
* @param maxRequests maximal amount of requests
19+
* @param maxTime amount of time until reset
20+
* @param maxUnit [ChronoUnit] of [maxTime]
21+
* @param name name of the request path
22+
* @param block the data fetcher
23+
*/
24+
fun <T : Any> ratelimitedDataFetcher(
25+
maxRequests: Int = RateLimiter.MAX_REQUESTS,
26+
maxTime: Long = 1,
27+
maxUnit: ChronoUnit = ChronoUnit.MINUTES,
28+
name: String,
29+
block: RatelimitedDataFetcher.DataFetchContext.() -> T
30+
): RatelimitedDataFetcher<T> {
31+
return object : RatelimitedDataFetcher<T> {
32+
override val maxRequests: Int
33+
get() = maxRequests
34+
35+
override val name: String
36+
get() = name
37+
38+
override val maxTime: Long
39+
get() = maxTime
40+
41+
override val maxUnit: ChronoUnit
42+
get() = maxUnit
43+
44+
override fun fetch(context: RatelimitedDataFetcher.DataFetchContext): T = block(context)
45+
}
46+
}
47+
48+
/**
49+
* Implementation of [DataFetcher] that uses [GatewayService.rateLimiter] to rate-limit requests.
50+
*/
51+
interface RatelimitedDataFetcher<T : Any> : DataFetcher<Any> {
52+
53+
/**
54+
* Maximal amount of requests
55+
*/
56+
val maxRequests: Int
57+
58+
/**
59+
* @see RateLimiter
60+
*/
61+
val maxTime: Long
62+
63+
/**
64+
* @see RateLimiter
65+
*/
66+
val maxUnit: ChronoUnit
67+
68+
/**
69+
* Name of the request
70+
*/
71+
val name: String
72+
73+
/**
74+
* Rate-limits requests before
75+
* @see DataFetcher.get
76+
*/
77+
override fun get(environment: DataFetchingEnvironment): Any {
78+
val context = environment.getContext<RequestContext>()
79+
val (pipelineContext, application) = context
80+
81+
val limit = application.rateLimiter.isRateLimited(pipelineContext, maxRequests, maxTime, maxUnit, name)
82+
83+
runBlocking {
84+
RateLimiter.addHeaders(limit, pipelineContext.call.response)
85+
}
86+
87+
if (limit.ratelimited) {
88+
return DataFetcherResult.newResult<T>()
89+
.error(
90+
GraphqlErrorBuilder.newError()
91+
.message("You're being ratelimited")
92+
.build()
93+
)
94+
.build()
95+
}
96+
97+
return fetch(DataFetchContext(context, environment))
98+
}
99+
100+
/**
101+
* Fetches the data.
102+
*/
103+
fun fetch(
104+
context: DataFetchContext
105+
): T
106+
107+
/**
108+
* Context for graphql data fetchers.
109+
* @property requestContext the [RequestContext] of the request
110+
* @property environment the [DataFetchingEnvironment]
111+
*/
112+
data class DataFetchContext(val requestContext: RequestContext, val environment: DataFetchingEnvironment) {
113+
114+
/**
115+
* Convenience getter.
116+
*/
117+
val pipelineContext: PipelineContext<*, ApplicationCall>
118+
get() = requestContext
119+
120+
/**
121+
* [GatewayService] instance.
122+
*/
123+
val application: GatewayService
124+
get() = requestContext.application
125+
}
126+
}

src/main/kotlin/app/ryss/gateway/gql/GraphQL.kt

+4-118
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,15 @@
11
package app.ryss.gateway.gql
22

33
import app.ryss.gateway.core.GatewayService
4-
import app.ryss.gateway.ratelimits.RateLimiter
5-
import graphql.GraphqlErrorBuilder
6-
import graphql.execution.DataFetcherResult
7-
import graphql.schema.*
4+
import graphql.schema.FieldCoordinates
5+
import graphql.schema.GraphQLCodeRegistry
6+
import graphql.schema.GraphQLObjectType
7+
import graphql.schema.GraphQLSchema
88
import io.ktor.application.ApplicationCall
9-
import io.ktor.application.call
109
import io.ktor.routing.Routing
1110
import io.ktor.util.pipeline.PipelineContext
12-
import kotlinx.coroutines.runBlocking
1311
import ktor.graphql.config
1412
import ktor.graphql.graphQL
15-
import java.time.temporal.ChronoUnit
1613

1714
/**
1815
* GraphQL manager.
@@ -55,117 +52,6 @@ class RequestContext(pipelineContext: PipelineContext<Unit, ApplicationCall>, va
5552
operator fun component2(): GatewayService = application
5653
}
5754

58-
/**
59-
* Creates an [RatelimitedDataFetcher] with [maxRequests] and [name].
60-
* @param maxRequests maximal amount of requests
61-
* @param maxTime amount of time until reset
62-
* @param maxUnit [ChronoUnit] of [maxTime]
63-
* @param name name of the request path
64-
* @param block the data fetcher
65-
*/
66-
fun <T : Any> ratelimitedDataFetcher(
67-
maxRequests: Int = RateLimiter.MAX_REQUESTS,
68-
maxTime: Long = 1,
69-
maxUnit: ChronoUnit = ChronoUnit.MINUTES,
70-
name: String,
71-
block: RatelimitedDataFetcher.DataFetchContext.() -> T
72-
): RatelimitedDataFetcher<T> {
73-
return object : RatelimitedDataFetcher<T> {
74-
override val maxRequests: Int
75-
get() = maxRequests
76-
77-
override val name: String
78-
get() = name
79-
80-
override val maxTime: Long
81-
get() = maxTime
82-
83-
override val maxUnit: ChronoUnit
84-
get() = maxUnit
85-
86-
override fun fetch(context: RatelimitedDataFetcher.DataFetchContext): T = block(context)
87-
}
88-
}
89-
90-
/**
91-
* Implementation of [DataFetcher] that uses [GatewayService.rateLimiter] to rate-limit requests.
92-
*/
93-
interface RatelimitedDataFetcher<T : Any> : DataFetcher<Any> {
94-
95-
/**
96-
* Maximal amount of requests
97-
*/
98-
val maxRequests: Int
99-
100-
/**
101-
* @see RateLimiter
102-
*/
103-
val maxTime: Long
104-
105-
/**
106-
* @see RateLimiter
107-
*/
108-
val maxUnit: ChronoUnit
109-
110-
/**
111-
* Name of the request
112-
*/
113-
val name: String
114-
115-
/**
116-
* Rate-limits requests before
117-
* @see DataFetcher.get
118-
*/
119-
override fun get(environment: DataFetchingEnvironment): Any {
120-
val context = environment.getContext<RequestContext>()
121-
val (pipelineContext, application) = context
122-
123-
val limit = application.rateLimiter.isRateLimited(pipelineContext, maxRequests, maxTime, maxUnit, name)
124-
125-
runBlocking {
126-
RateLimiter.addHeaders(limit, pipelineContext.call.response)
127-
}
128-
129-
if (limit.ratelimited) {
130-
return DataFetcherResult.newResult<T>()
131-
.error(
132-
GraphqlErrorBuilder.newError()
133-
.message("You're being ratelimited")
134-
.build()
135-
)
136-
.build()
137-
}
138-
139-
return fetch(DataFetchContext(context, environment))
140-
}
141-
142-
/**
143-
* Fetches the data.
144-
*/
145-
fun fetch(
146-
context: DataFetchContext
147-
): T
148-
149-
/**
150-
* Context for graphql data fetchers.
151-
* @property requestContext the [RequestContext] of the request
152-
* @property environment the [DataFetchingEnvironment]
153-
*/
154-
data class DataFetchContext(val requestContext: RequestContext, val environment: DataFetchingEnvironment) {
155-
156-
/**
157-
* Convenience getter.
158-
*/
159-
val pipelineContext: PipelineContext<*, ApplicationCall>
160-
get() = requestContext
161-
162-
/**
163-
* [GatewayService] instance.
164-
*/
165-
val application: GatewayService
166-
get() = requestContext.application
167-
}
168-
}
16955

17056
private fun buildSchema(): GraphQLSchema {
17157
return GraphQLSchema.newSchema()

0 commit comments

Comments
 (0)