|
1 | 1 | package app.ryss.gateway.gql
|
2 | 2 |
|
3 | 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.* |
| 4 | +import graphql.schema.FieldCoordinates |
| 5 | +import graphql.schema.GraphQLCodeRegistry |
| 6 | +import graphql.schema.GraphQLObjectType |
| 7 | +import graphql.schema.GraphQLSchema |
8 | 8 | import io.ktor.application.ApplicationCall
|
9 |
| -import io.ktor.application.call |
10 | 9 | import io.ktor.routing.Routing
|
11 | 10 | import io.ktor.util.pipeline.PipelineContext
|
12 |
| -import kotlinx.coroutines.runBlocking |
13 | 11 | import ktor.graphql.config
|
14 | 12 | import ktor.graphql.graphQL
|
15 |
| -import java.time.temporal.ChronoUnit |
16 | 13 |
|
17 | 14 | /**
|
18 | 15 | * GraphQL manager.
|
@@ -55,117 +52,6 @@ class RequestContext(pipelineContext: PipelineContext<Unit, ApplicationCall>, va
|
55 | 52 | operator fun component2(): GatewayService = application
|
56 | 53 | }
|
57 | 54 |
|
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 |
| -} |
169 | 55 |
|
170 | 56 | private fun buildSchema(): GraphQLSchema {
|
171 | 57 | return GraphQLSchema.newSchema()
|
|
0 commit comments