Skip to content

Commit

Permalink
feat: add dataFetcherResult option to return both errors and partial …
Browse files Browse the repository at this point in the history
…data (#126)
  • Loading branch information
vmiliantsei authored Jan 14, 2025
1 parent f46b5da commit 5df1e00
Show file tree
Hide file tree
Showing 9 changed files with 98 additions and 3 deletions.
8 changes: 7 additions & 1 deletion src/config/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@ export const configSchema = object({
*
* Type names can be optionally passed with the classMethods config to generate the interface with `suspend` functions or
* `java.util.concurrent.CompletableFuture` functions. Pass `nullableDataFetchingEnvironment: true` to make the
* `DataFetchingEnvironment` argument nullable in each resolver function for that class.
* `DataFetchingEnvironment` argument nullable in each resolver function for that class. Pass `dataFetcherResult: true`
* to make functions return `DataFetcherResult` to hold both data and errors.
* @example
* [
* {
Expand All @@ -138,6 +139,10 @@ export const configSchema = object({
* {
* typeName: "MyTypeWithNullableDataFetchingEnvironment",
* nullableDataFetchingEnvironment: true,
* },
* {
* typeName: "MyTypeWithPartialData",
* dataFetcherResult: true,
* }
* ]
* @link https://opensource.expediagroup.com/graphql-kotlin-codegen/docs/recommended-usage
Expand All @@ -150,6 +155,7 @@ export const configSchema = object({
union([literal("SUSPEND"), literal("COMPLETABLE_FUTURE")]),
),
nullableDataFetchingEnvironment: optional(boolean()),
dataFetcherResult: optional(boolean()),
}),
),
),
Expand Down
9 changes: 7 additions & 2 deletions src/definitions/field.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,13 @@ function buildField(
);
const isCompletableFuture =
typeInResolverInterfacesConfig?.classMethods === "COMPLETABLE_FUTURE";
const completableFutureDefinition = `java.util.concurrent.CompletableFuture<${typeMetadata.typeName}${typeMetadata.isNullable ? "?" : ""}> = ${defaultImplementation}`;
const defaultDefinition = `${typeMetadata.typeName}${defaultDefinitionValue}`;
let typeDefinition = `${typeMetadata.typeName}${typeMetadata.isNullable ? "?" : ""}`;
let defaultDefinition = `${typeMetadata.typeName}${defaultDefinitionValue}`;
if (typeInResolverInterfacesConfig?.dataFetcherResult) {
typeDefinition = `graphql.execution.DataFetcherResult<${typeDefinition}>`;
defaultDefinition = `${typeDefinition} = ${defaultImplementation}`;
}
const completableFutureDefinition = `java.util.concurrent.CompletableFuture<${typeDefinition}> = ${defaultImplementation}`;
return indent(
`${functionDefinition}: ${isCompletableFuture ? completableFutureDefinition : defaultDefinition}`,
2,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { GraphQLKotlinCodegenConfig } from "../../../src/plugin";

export default {
resolverInterfaces: [
{
typeName: "DataFetcherResultCompletableFutureType",
classMethods: "COMPLETABLE_FUTURE",
dataFetcherResult: true,
},
],
} satisfies GraphQLKotlinCodegenConfig;
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.kotlin.generated

import com.expediagroup.graphql.generator.annotations.*

@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT])
open class DataFetcherResultCompletableFutureType {
open fun stringField1(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): java.util.concurrent.CompletableFuture<graphql.execution.DataFetcherResult<String?>> = throw NotImplementedError("DataFetcherResultCompletableFutureType.stringField1 must be implemented.")
open fun stringField2(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): java.util.concurrent.CompletableFuture<graphql.execution.DataFetcherResult<String>> = throw NotImplementedError("DataFetcherResultCompletableFutureType.stringField2 must be implemented.")
open fun booleanField1(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): java.util.concurrent.CompletableFuture<graphql.execution.DataFetcherResult<Boolean?>> = throw NotImplementedError("DataFetcherResultCompletableFutureType.booleanField1 must be implemented.")
open fun booleanField2(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): java.util.concurrent.CompletableFuture<graphql.execution.DataFetcherResult<Boolean>> = throw NotImplementedError("DataFetcherResultCompletableFutureType.booleanField2 must be implemented.")
open fun integerField1(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): java.util.concurrent.CompletableFuture<graphql.execution.DataFetcherResult<Int?>> = throw NotImplementedError("DataFetcherResultCompletableFutureType.integerField1 must be implemented.")
open fun integerField2(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): java.util.concurrent.CompletableFuture<graphql.execution.DataFetcherResult<Int>> = throw NotImplementedError("DataFetcherResultCompletableFutureType.integerField2 must be implemented.")
open fun listField(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): java.util.concurrent.CompletableFuture<graphql.execution.DataFetcherResult<List<String>>> = throw NotImplementedError("DataFetcherResultCompletableFutureType.listField must be implemented.")
open fun listField2(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): java.util.concurrent.CompletableFuture<graphql.execution.DataFetcherResult<List<String?>>> = throw NotImplementedError("DataFetcherResultCompletableFutureType.listField2 must be implemented.")
open fun listField3(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): java.util.concurrent.CompletableFuture<graphql.execution.DataFetcherResult<List<String>?>> = throw NotImplementedError("DataFetcherResultCompletableFutureType.listField3 must be implemented.")
open fun listField4(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): java.util.concurrent.CompletableFuture<graphql.execution.DataFetcherResult<List<String?>?>> = throw NotImplementedError("DataFetcherResultCompletableFutureType.listField4 must be implemented.")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
type DataFetcherResultCompletableFutureType {
stringField1: String
stringField2: String!
booleanField1: Boolean
booleanField2: Boolean!
integerField1: Int
integerField2: Int!
listField: [String!]!
listField2: [String]!
listField3: [String!]
listField4: [String]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { GraphQLKotlinCodegenConfig } from "../../../src/plugin";

export default {
resolverInterfaces: [
{
typeName: "DataFetcherResultSuspendType",
classMethods: "SUSPEND",
dataFetcherResult: true,
},
],
} satisfies GraphQLKotlinCodegenConfig;
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.kotlin.generated

import com.expediagroup.graphql.generator.annotations.*

@GraphQLValidObjectLocations(locations = [GraphQLValidObjectLocations.Locations.OBJECT])
open class DataFetcherResultSuspendType {
open suspend fun stringField1(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): graphql.execution.DataFetcherResult<String?> = throw NotImplementedError("DataFetcherResultSuspendType.stringField1 must be implemented.")
open suspend fun stringField2(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): graphql.execution.DataFetcherResult<String> = throw NotImplementedError("DataFetcherResultSuspendType.stringField2 must be implemented.")
open suspend fun booleanField1(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): graphql.execution.DataFetcherResult<Boolean?> = throw NotImplementedError("DataFetcherResultSuspendType.booleanField1 must be implemented.")
open suspend fun booleanField2(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): graphql.execution.DataFetcherResult<Boolean> = throw NotImplementedError("DataFetcherResultSuspendType.booleanField2 must be implemented.")
open suspend fun integerField1(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): graphql.execution.DataFetcherResult<Int?> = throw NotImplementedError("DataFetcherResultSuspendType.integerField1 must be implemented.")
open suspend fun integerField2(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): graphql.execution.DataFetcherResult<Int> = throw NotImplementedError("DataFetcherResultSuspendType.integerField2 must be implemented.")
open suspend fun listField(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): graphql.execution.DataFetcherResult<List<String>> = throw NotImplementedError("DataFetcherResultSuspendType.listField must be implemented.")
open suspend fun listField2(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): graphql.execution.DataFetcherResult<List<String?>> = throw NotImplementedError("DataFetcherResultSuspendType.listField2 must be implemented.")
open suspend fun listField3(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): graphql.execution.DataFetcherResult<List<String>?> = throw NotImplementedError("DataFetcherResultSuspendType.listField3 must be implemented.")
open suspend fun listField4(dataFetchingEnvironment: graphql.schema.DataFetchingEnvironment): graphql.execution.DataFetcherResult<List<String?>?> = throw NotImplementedError("DataFetcherResultSuspendType.listField4 must be implemented.")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
type DataFetcherResultSuspendType {
stringField1: String
stringField2: String!
booleanField1: Boolean
booleanField2: Boolean!
integerField1: Int
integerField2: Int!
listField: [String!]!
listField2: [String]!
listField3: [String!]
listField4: [String]
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,9 @@ export default {
typeName: "MyIncludedResolverTypeWithNullDataFetchingEnvironment",
nullableDataFetchingEnvironment: true,
},
{
typeName: "MyTypeWithPartialData",
dataFetcherResult: true,
},
],
} satisfies GraphQLKotlinCodegenConfig;

0 comments on commit 5df1e00

Please sign in to comment.