-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add execution stats to GraphQL responses
- Loading branch information
1 parent
03875e1
commit 57a0935
Showing
10 changed files
with
113 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
35 changes: 35 additions & 0 deletions
35
src/main/kotlin/info/jotajoti/jampuz/graphql/CostDirective.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package info.jotajoti.jampuz.graphql | ||
|
||
import graphql.schema.* | ||
import graphql.schema.idl.* | ||
import graphql.schema.idl.RuntimeWiring.* | ||
import org.springframework.graphql.server.* | ||
|
||
fun Builder.registerCostDirective(): Builder = | ||
directive("Cost", CostDirective) | ||
|
||
val WebGraphQlResponse.calculatedCost: Int get() = executionInput.graphQLContext.getOrDefault(COST_KEY, 0) | ||
|
||
private object CostDirective : SchemaDirectiveWiring { | ||
override fun onField(environment: SchemaDirectiveWiringEnvironment<GraphQLFieldDefinition>): GraphQLFieldDefinition = | ||
environment.setFieldDataFetcher( | ||
CostDataFetcher( | ||
environment.appliedDirective, | ||
environment.fieldDataFetcher | ||
) | ||
) | ||
} | ||
|
||
private class CostDataFetcher<T>(val appliedDirective: GraphQLAppliedDirective, dataFetcher: DataFetcher<T>) : | ||
DataFetcherDelegate<T>(dataFetcher) { | ||
|
||
override fun get(environment: DataFetchingEnvironment): T { | ||
val cost = appliedDirective.getArgument("value").getValue<Int>() | ||
environment.graphQlContext.compute<Int>(COST_KEY) { t, u -> | ||
u?.let { u + cost } ?: cost | ||
} | ||
return super.get(environment) | ||
} | ||
} | ||
|
||
private const val COST_KEY = "cost" |
11 changes: 11 additions & 0 deletions
11
src/main/kotlin/info/jotajoti/jampuz/graphql/DataFetcherDelegate.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package info.jotajoti.jampuz.graphql | ||
|
||
import graphql.schema.DataFetcher | ||
import graphql.schema.DataFetchingEnvironment | ||
|
||
abstract class DataFetcherDelegate<T>(val dataFetcher: DataFetcher<T>) : DataFetcher<T> { | ||
|
||
override fun get(environment: DataFetchingEnvironment): T { | ||
return dataFetcher.get(environment) | ||
} | ||
} |
33 changes: 33 additions & 0 deletions
33
src/main/kotlin/info/jotajoti/jampuz/graphql/GraphQLQueryStatsInterceptor.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package info.jotajoti.jampuz.graphql | ||
|
||
import org.springframework.graphql.server.* | ||
import org.springframework.graphql.server.WebGraphQlInterceptor.* | ||
import org.springframework.stereotype.* | ||
import reactor.core.publisher.* | ||
|
||
@Component | ||
class GraphQLQueryStatsInterceptor : WebGraphQlInterceptor { | ||
|
||
override fun intercept(request: WebGraphQlRequest, chain: Chain): Mono<WebGraphQlResponse> { | ||
val start = System.currentTimeMillis() | ||
|
||
return chain.next(request).map { response -> | ||
val end = System.currentTimeMillis() | ||
response.transform { | ||
it.extensions( | ||
mapOf( | ||
"executionStats" to ExecutionStats( | ||
duration = end - start, | ||
cost = response.calculatedCost | ||
) | ||
) | ||
) | ||
} | ||
} | ||
} | ||
} | ||
|
||
data class ExecutionStats( | ||
val duration: Long, | ||
val cost: Int, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters