Skip to content

Separate nullableFieldStyle Configuration for Input types and response type? #6175

Open
@Mohammad-Dwairi

Description

@Mohammad-Dwairi

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions