Skip to content

Commit 399e6a7

Browse files
authored
[plugins] allow specifying custom headers for introspection/downloadSDL tasks (#728)
* [plugins] allow specifying custom headers for introspection/downloadSDL tasks Update introspection and downloadSDL tasks/mojos to accept list of headers. See updated plugin documentation for details. Resolves: #722 * remove commented out build config
1 parent dfa5661 commit 399e6a7

File tree

36 files changed

+861
-141
lines changed

36 files changed

+861
-141
lines changed

docs/plugins/gradle-plugin.md

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,14 @@ graphql {
3838
sdlEndpoint = "http://localhost:8080/sdl"
3939
// Target package name to be used for generated classes.
4040
packageName = "com.example.generated"
41+
// Optional HTTP headers to be specified on an introspection query or SDL request.
42+
headers["X-Custom-Header"] = "Custom-Header-Value"
4143
// Boolean flag indicating whether or not selection of deprecated fields is allowed.
4244
allowDeprecatedFields = false
4345
// Custom GraphQL scalar to converter mapping containing information about corresponding Java type and converter that should be used to serialize/deserialize values.
44-
converters.put("UUID", ScalarConverterMapping("java.util.UUID", "com.example.UUIDScalarConverter"))
46+
converters["UUID"] = ScalarConverterMapping("java.util.UUID", "com.example.UUIDScalarConverter")
47+
// List of query files to be processed.
48+
queryFiles.add(file("${project.projectDir}/src/main/resources/queries/MyQuery.graphql"))
4549
}
4650
}
4751
```
@@ -63,6 +67,7 @@ and could be used as an alternative to `graphqlIntrospectSchema` to generate inp
6367
| Property | Type | Required | Description |
6468
| -------- | ---- | -------- | ----------- |
6569
| `endpoint` | String | yes | Target GraphQL server SDL endpoint that will be used to download schema.<br/>**Command line property is**: `endpoint`. |
70+
| `headers` | Map<String, Any> | | Optional HTTP headers to be specified on a SDL request. |
6671

6772
### graphqlGenerateClient
6873

@@ -115,6 +120,7 @@ should be used to generate input for the subsequent `graphqlGenerateClient` task
115120
| Property | Type | Required | Description |
116121
| -------- | ---- | -------- | ----------- |
117122
| `endpoint` | String | yes | Target GraphQL server endpoint that will be used to execute introspection queries.<br/>**Command line property is**: `endpoint`. |
123+
| `headers` | Map<String, Any> | | Optional HTTP headers to be specified on an introspection query. |
118124

119125
## Examples
120126

@@ -193,7 +199,7 @@ val graphqlGenerateClient by tasks.getting(GraphQLGenerateClientTask::class) {
193199
This will process all GraphQL queries located under `src/main/resources` and generate corresponding GraphQL Kotlin clients.
194200
Generated classes will be automatically added to the project compile sources.
195201

196-
### Generating client with Custom Scalars
202+
### Generating Client with Custom Scalars
197203

198204
By default, all custom GraphQL scalars will be serialized as Strings. You can override this default behavior by specifying
199205
custom [scalar converter](https://github.com/ExpediaGroup/graphql-kotlin/blob/master/graphql-kotlin-client/src/main/kotlin/com/expediagroup/graphql/client/converter/ScalarConverter.kt).
@@ -259,7 +265,7 @@ Generated classes will be automatically added to the project test compile source
259265

260266
>NOTE: `graphqlGenerateTestClient` cannot be configured through the `graphql` extension and has to be explicitly configured.
261267
262-
### Complete Configuration Example
268+
### Complete Minimal Configuration Example
263269

264270
Following is the minimal configuration that runs introspection query against a target GraphQL server and generates a
265271
corresponding schema. This generated schema is subsequently used to generate GraphQL client code based on the queries
@@ -293,3 +299,48 @@ val graphqlGenerateClient by tasks.getting(GraphQLGenerateClientTask::class) {
293299
dependsOn("graphqlIntrospectSchema")
294300
}
295301
```
302+
303+
### Complete Configuration Example
304+
305+
Following is a configuration example that downloads schema SDL from a target GraphQL server that is then used to generate
306+
the GraphQL client code based on the provided query.
307+
308+
```kotlin
309+
// build.gradle.kts
310+
import com.expediagroup.graphql.plugin.gradle.graphql
311+
312+
graphql {
313+
client {
314+
sdlEndpoint = "http://localhost:8080/sdl"
315+
packageName = "com.example.generated"
316+
// optional configuration
317+
allowDeprecatedFields = true
318+
headers["X-Custom-Header"] = "My-Custom-Header"
319+
converters["UUID"] = ScalarConverterMapping("java.util.UUID", "com.example.UUIDScalarConverter")
320+
queryFiles.add(file("${project.projectDir}/src/main/resources/queries/MyQuery.graphql"))
321+
}
322+
}
323+
```
324+
325+
Above configuration is equivalent to the following
326+
327+
```kotlin
328+
// build.gradle.kts
329+
import com.expediagroup.graphql.plugin.gradle.tasks.GraphQLDownloadSDLTask
330+
import com.expediagroup.graphql.plugin.gradle.tasks.GraphQLIntrospectSchemaTask
331+
332+
val graphqlDownloadSDL by tasks.getting(GraphQLDownloadSDLTask::class) {
333+
endpoint.set("http://localhost:8080/sdl")
334+
headers.put("X-Custom-Header", "My-Custom-Header")
335+
}
336+
val graphqlGenerateClient by tasks.getting(GraphQLGenerateClientTask::class) {
337+
packageName.set("com.example.generated")
338+
schemaFile.set(graphqlDownloadSDL.outputFile)
339+
// optional
340+
allowDeprecatedFields.set(true)
341+
converters.put("UUID", ScalarConverterMapping("java.util.UUID", "com.example.UUIDScalarConverter"))
342+
queryFiles.from("${project.projectDir}/src/main/resources/queries/MyQuery.graphql")
343+
344+
dependsOn("graphqlDownloadSDL")
345+
}
346+
```

docs/plugins/maven-plugin.md

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ goal provides limited functionality by itself and instead should be used to gene
2828
| Property | Type | Required | Description |
2929
| -------- | ---- | -------- | ----------- |
3030
| `endpoint` | String | yes | Target GraphQL server SDL endpoint that will be used to download schema.<br/>**User property is**: `graphql.endpoint`. |
31+
| `headers` | Map<String, Any> | | Optional HTTP headers to be specified on a SDL request.
3132

3233
### generate-client
3334

@@ -122,6 +123,7 @@ should be used to generate input for the subsequent `generate-client` goal.
122123
| Property | Type | Required | Description |
123124
| -------- | ---- | -------- | ----------- |
124125
| `endpoint` | String | yes | Target GraphQL server endpoint that will be used to execute introspection queries.<br/>**User property is**: `graphql.endpoint`. |
126+
| `headers` | Map<String, Any> | | Optional HTTP headers to be specified on an introspection query. |
125127

126128
## Examples
127129

@@ -320,7 +322,7 @@ Generated classes will be automatically added to the project test compile source
320322
>NOTE: You might need to explicitly add generated test clients to your project test sources for your IDE to recognize them.
321323
>See [build-helper-maven-plugin](https://www.mojohaus.org/build-helper-maven-plugin/) for details.
322324
323-
### Complete Configuration Example
325+
### Complete Minimal Configuration Example
324326

325327
Following is the minimal configuration that runs introspection query against a target GraphQL server and generates a corresponding schema.
326328
This generated schema is subsequently used to generate GraphQL client code based on the queries provided under `src/main/resources` directory.
@@ -349,3 +351,47 @@ This generated schema is subsequently used to generate GraphQL client code based
349351
>NOTE: Both `introspect-schema` and `generate-client` goals are bound to the same `generate-sources` Maven lifecycle phase.
350352
>As opposed to Gradle, Maven does not support explicit ordering of different goals bound to the same build phase. Maven
351353
>Mojos will be executed in the order they are defined in your `pom.xml` build file.
354+
355+
### Complete Configuration Example
356+
357+
Following is a configuration example that downloads schema SDL from a target GraphQL server that is then used to generate
358+
the GraphQL client code based on the provided query.
359+
360+
```xml
361+
<plugin>
362+
<groupId>com.expediagroup</groupId>
363+
<artifactId>graphql-kotlin-maven-plugin</artifactId>
364+
<version>${graphql-kotlin.version}</version>
365+
<executions>
366+
<execution>
367+
<goals>
368+
<goal>download-sdl</goal>
369+
<goal>generate-client</goal>
370+
</goals>
371+
<configuration>
372+
<endpoint>http://localhost:8080/sdl</endpoint>
373+
<packageName>com.example.generated</packageName>
374+
<schemaFile>${project.build.directory}/schema.graphql</schemaFile>
375+
<!-- optional configuration below -->
376+
<allowDeprecatedFields>true</allowDeprecatedFields>
377+
<headers>
378+
<X-Custom-Header>My-Custom-Header</X-Custom-Header>
379+
</headers>
380+
<converters>
381+
<!-- custom scalar UUID type -->
382+
<UUID>
383+
<!-- fully qualified Java class name of a custom scalar type -->
384+
<type>java.util.UUID</type>
385+
<!-- fully qualified Java class name of a custom com.expediagroup.graphql.client.converter.ScalarConverter
386+
used to convert to/from raw JSON and scalar type -->
387+
<converter>com.example.UUIDScalarConverter</converter>
388+
</UUID>
389+
</converters>
390+
<queryFiles>
391+
<queryFile>${project.basedir}/src/main/resources/queries/MyQuery.graphql</queryFile>
392+
</queryFiles>
393+
</configuration>
394+
</execution>
395+
</executions>
396+
</plugin>
397+
```

examples/client/gradle-client/build.gradle.kts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import com.expediagroup.graphql.plugin.generator.ScalarConverterMapping
22
import com.expediagroup.graphql.plugin.gradle.graphql
3+
import com.expediagroup.graphql.plugin.gradle.tasks.GraphQLDownloadSDLTask
4+
import com.expediagroup.graphql.plugin.gradle.tasks.GraphQLGenerateClientTask
35

46
plugins {
57
application
@@ -40,11 +42,12 @@ graphql {
4042
packageName = "com.expediagroup.graphql.generated"
4143
// you can also use direct sdlEndpoint instead
4244
endpoint = "http://localhost:8080/graphql"
43-
allowDeprecatedFields = true
45+
4446
// optional
47+
allowDeprecatedFields = true
48+
headers["X-Custom-Header"] = "My-Custom-Header"
4549
converters["UUID"] = ScalarConverterMapping("java.util.UUID", "com.expediagroup.graphql.examples.client.UUIDScalarConverter")
4650
}
47-
4851
}
4952

5053
tasks {

examples/client/maven-client/pom.xml

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
<!-- lib versions -->
1313
<kotlin.version>1.3.72</kotlin.version>
1414
<kotlin-coroutines.version>1.3.6</kotlin-coroutines.version>
15+
<ktor.version>1.3.1</ktor.version>
1516
</properties>
1617

1718
<dependencies>
@@ -20,6 +21,16 @@
2021
<artifactId>graphql-kotlin-client</artifactId>
2122
<version>${graphql-kotlin.version}</version>
2223
</dependency>
24+
<dependency>
25+
<groupId>io.ktor</groupId>
26+
<artifactId>ktor-client-okhttp</artifactId>
27+
<version>${ktor.version}</version>
28+
</dependency>
29+
<dependency>
30+
<groupId>io.ktor</groupId>
31+
<artifactId>ktor-client-logging-jvm</artifactId>
32+
<version>${ktor.version}</version>
33+
</dependency>
2334
</dependencies>
2435

2536
<build>
@@ -47,22 +58,18 @@
4758
<version>${graphql-kotlin.version}</version>
4859
<executions>
4960
<execution>
50-
<id>introspect-schema</id>
5161
<goals>
5262
<goal>introspect-schema</goal>
53-
</goals>
54-
<configuration>
55-
<endpoint>http://localhost:8080/graphql</endpoint>
56-
</configuration>
57-
</execution>
58-
<execution>
59-
<id>generate-client</id>
60-
<goals>
6163
<goal>generate-client</goal>
6264
</goals>
6365
<configuration>
66+
<endpoint>http://localhost:8080/graphql</endpoint>
6467
<packageName>com.expediagroup.graphql.generated</packageName>
6568
<schemaFile>${project.build.directory}/schema.graphql</schemaFile>
69+
<allowDeprecatedFields>true</allowDeprecatedFields>
70+
<headers>
71+
<X-Custom-Header>My-Custom-Header</X-Custom-Header>
72+
</headers>
6673
<converters>
6774
<!-- custom scalar UUID type -->
6875
<UUID>

examples/client/maven-client/src/main/kotlin/com/expediagroup/graphql/examples/client/Application.kt

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,34 @@ import com.expediagroup.graphql.generated.HelloWorldQuery
66
import com.expediagroup.graphql.generated.RetrieveObjectQuery
77
import com.expediagroup.graphql.generated.UpdateObjectMutation
88
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
9-
import io.ktor.client.HttpClient
109
import io.ktor.client.engine.okhttp.OkHttp
11-
import io.ktor.client.engine.okhttp.OkHttpEngine
10+
import io.ktor.client.features.logging.DEFAULT
11+
import io.ktor.client.features.logging.LogLevel
12+
import io.ktor.client.features.logging.Logger
13+
import io.ktor.client.features.logging.Logging
1214
import kotlinx.coroutines.runBlocking
1315
import java.net.URL
1416
import java.util.concurrent.TimeUnit
1517

1618
fun main() {
17-
val okHttpEngine = OkHttp.create {
18-
config {
19-
connectTimeout(1, TimeUnit.SECONDS)
20-
readTimeout(60, TimeUnit.SECONDS)
21-
writeTimeout(60, TimeUnit.SECONDS)
19+
val jackson = jacksonObjectMapper()
20+
val client = GraphQLClient(
21+
url = URL("http://localhost:8080/graphql"),
22+
engineFactory = OkHttp,
23+
mapper = jackson
24+
) {
25+
engine {
26+
config {
27+
connectTimeout(10, TimeUnit.SECONDS)
28+
readTimeout(60, TimeUnit.SECONDS)
29+
writeTimeout(60, TimeUnit.SECONDS)
30+
}
31+
}
32+
install(Logging) {
33+
logger = Logger.DEFAULT
34+
level = LogLevel.HEADERS
2235
}
23-
// addInterceptor(myInterceptor)
2436
}
25-
val customObjectMapper = jacksonObjectMapper()
26-
val client = GraphQLClient(url = URL("http://localhost:8080/graphql"), mapper = customObjectMapper)
2737
val helloWorldQuery = HelloWorldQuery(client)
2838
println("HelloWorld examples")
2939
runBlocking {

gradle.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ springBootVersion = 2.2.6.RELEASE
3030
# test dependency versions
3131
junitVersion = 5.6.0
3232
mockkVersion = 1.9.3
33+
mustacheVersion = 0.9.6
3334
rxjavaVersion = 3.0.1
3435
wireMockVersion = 2.26.2
3536

plugins/graphql-kotlin-gradle-plugin/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ and could be used as an alternative to `graphqlIntrospectSchema` to generate inp
4646
| Property | Type | Required | Description |
4747
| -------- | ---- | -------- | ----------- |
4848
| `endpoint` | String | yes | Target GraphQL server SDL endpoint that will be used to download schema.<br/>**Command line property is**: `endpoint`. |
49+
| `headers` | Map<String, Any> | | Optional HTTP headers to be specified on a SDL request. |
4950

5051
### graphqlGenerateClient
5152

@@ -98,6 +99,7 @@ should be used to generate input for the subsequent `graphqlGenerateClient` task
9899
| Property | Type | Required | Description |
99100
| -------- | ---- | -------- | ----------- |
100101
| `endpoint` | String | yes | Target GraphQL server endpoint that will be used to execute introspection queries.<br/>**Command line property is**: `endpoint`. |
102+
| `headers` | Map<String, Any> | | Optional HTTP headers to be specified on an introspection query. |
101103

102104
## Documentation
103105

plugins/graphql-kotlin-gradle-plugin/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@ plugins {
77

88
val kotlinCoroutinesVersion: String by project
99
val wireMockVersion: String by project
10+
val mustacheVersion: String by project
1011

1112
dependencies {
1213
api(project(path = ":graphql-kotlin-plugin-core"))
1314
api("org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlinCoroutinesVersion")
1415
testImplementation(project(path = ":graphql-kotlin-client"))
1516
testImplementation("com.github.tomakehurst:wiremock-jre8:$wireMockVersion")
17+
testImplementation("com.github.spullara.mustache.java:compiler:$mustacheVersion")
1618
}
1719

1820
gradlePlugin {

plugins/graphql-kotlin-gradle-plugin/src/main/kotlin/com/expediagroup/graphql/plugin/gradle/GraphQLGradlePlugin.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,13 @@ class GraphQLGradlePlugin : Plugin<Project> {
6666
if (extension.clientExtension.endpoint != null) {
6767
val introspectSchemaTask = project.tasks.named(INTROSPECT_SCHEMA_TASK_NAME, GraphQLIntrospectSchemaTask::class.java).get()
6868
introspectSchemaTask.endpoint.convention(project.provider { extension.clientExtension.endpoint })
69+
introspectSchemaTask.headers.convention(project.provider { extension.clientExtension.headers })
6970
generateClientTask.dependsOn(introspectSchemaTask.path)
7071
generateClientTask.schemaFile.convention(introspectSchemaTask.outputFile)
7172
} else if (extension.clientExtension.sdlEndpoint != null) {
7273
val downloadSDLTask = project.tasks.named(DOWNLOAD_SDL_TASK_NAME, GraphQLDownloadSDLTask::class.java).get()
73-
downloadSDLTask.endpoint.convention(project.provider { extension.clientExtension.endpoint })
74+
downloadSDLTask.endpoint.convention(project.provider { extension.clientExtension.sdlEndpoint })
75+
downloadSDLTask.headers.convention(project.provider { extension.clientExtension.headers })
7476
generateClientTask.dependsOn(downloadSDLTask.path)
7577
generateClientTask.schemaFile.convention(downloadSDLTask.outputFile)
7678
} else {

plugins/graphql-kotlin-gradle-plugin/src/main/kotlin/com/expediagroup/graphql/plugin/gradle/GraphQLPluginExtension.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ open class GraphQLPluginClientExtension {
4646
var sdlEndpoint: String? = null
4747
/** Target package name to be used for generated classes. */
4848
var packageName: String? = null
49+
/** Optional HTTP headers to be specified on an introspection query or SDL request. */
50+
var headers: MutableMap<String, Any> = mutableMapOf()
4951
/** Boolean flag indicating whether or not selection of deprecated fields is allowed. */
5052
var allowDeprecatedFields: Boolean = false
5153
/** Custom GraphQL scalar to converter mapping containing information about corresponding Java type and converter that should be used to serialize/deserialize values. */

0 commit comments

Comments
 (0)