Description
Question
I'm generating Java models and trying to configure nullable fields in the response to be wrapped in Optional
using nullableFieldStyle.set("javaOptional")
.
However, this setting seems to be applied to both input
types and response type
in the schema. Is there a way to restrict this configuration so that it only affects nullable fields in the response models type X
? maybe by having separate configuration options for input types and response types?
Configuration Sample
service("xyz") {
generateKotlinModels.set(false)
nullableFieldStyle.set("javaOptional")
generateOptionalOperationVariables.set(false)
}
Bug?
Using the configurations shown above, the Optional
wrapper is applied to nullable fields inside input
types but not applied to top-level nullable input variables. This inconsistency causes the generated builder to treat top-level nullable input variables as plain types instead of wrapping them in Optional.
I'm not entirely sure which behavior is expected in this case: whether the Optional
wrapper should be applied uniformly to all nullable fields or if the difference between top-level variables and fields inside input
types is intentional, or if it shouldn't wrap any input variable in Optional
since generateOptionalOperationVariables
is set to false
(I think this makes most sense).
I believe there is a small conflict between nullableFieldStyle
and generateOptionalOperationVariables
options, since applying nullableFieldStyle
option will indirectly apply Optional
wrappers to the input
types fields.
nullableFieldStyle |
generateOptionalOperationVariables |
Effect on Operation Variables | Effect on Response Fields |
---|---|---|---|
Applied | true | All nullable operation variables are wrapped in Optional |
Nullable fields are wrapped in Optional |
Applied | false | Only nullable fields in input types are wrapped in Optional |
Nullable fields are wrapped in Optional |
Not Applied | true | Nullable Operation variables are wrapped in Optional internally, but not in the input builders. Expected? |
Nothing is wrapped with Optional |
Not Applied | false | Nothing is wrapped in Optional |
Nothing is wrapped in Optional |
Example
Input type
input CheckOutDateFilter {
from: String # nullable
to: String # nullable
}
Sample Query
query PropertyReservations(
$propertyId: String!,
$checkOutDate: CheckOutDateFilter # nullable
$cursor: String # nullable
) {
....
}
Generated Builder
CheckOutDateFilter checkOutDateFilter = CheckOutDateFilter
.builder()
.from(Optional.empty()) // The builder expects this param as Optional<String>
.to(Optional.empty()) // The builder expects this param as Optional<String>
.build();
PropertyReservationsQuery reservationsQuery = PropertyReservationsQuery
.builder()
.propertyId(propertyId)
.cursor(null) // The builder expects this param as String, not Optional<String> although it's nullable
.checkOutDate(checkOutDateFilter) // The builder expects this param as CheckOutDateFilter, not Optional<CheckOutDateFilter> although it's nullable
.build();
The top-level nullable input variables (cursor
and checkOutDate
) are not wrapped in Optional
, whereas the fields inside the input type CheckOutDateFilter
are wrapped in Optional
.
Apollo Version
v 4.0.0