Add support for `Optional<T>` in Dart generator (both dart and dart-dio) to distinguish absent, null, and present states

Merged
EI
8mo ago
+657-18

fixes #21826

I saw in the guidelines that you guys don't want too many flags, well, here are two more:

  • useOptional=true: Enable Optional support all over, and
  • patchOnly=true: Automatically apply Optional only to only PATCH request schemas

The second one there might seem silly, but it makes a lot of sense to only support absent fields for PATCH.
I had a look at the Java Nullable thing and there it seems it is applied all over, at least when I generated.
This might be fine, but not always.

Without the flags the generated stuff should be as before.

This PR require Dart 3 Optional, as I use this to make fields optional.

PR checklist

  • Read the contribution guidelines.
  • Pull Request title clearly describes the work in the pull request and Pull Request description provides details about how to validate the work. Missing information here may result in delayed response from the community.
  • Run the following to build the project and update samples:
    ./mvnw clean package || exit
    ./bin/generate-samples.sh ./bin/configs/*.yaml || exit
    ./bin/utils/export_docs_generators.sh || exit
    

clean package works fine, the other two, I don't know what to do.

  • File the PR against the correct branch: master (upcoming 7.x.0 minor release - breaking changes with fallbacks), 8.0.x (breaking changes without fallbacks)

I guess...

  • If your PR solves a reported issue, reference it using GitHub's linking syntax (e.g., having "fixes #123" present in the PR description)
  • If your PR is targeting a particular programming language, @mention the technical committee members, so they are more likely to review the pull request.

@josh-burton
@yissachar

Some details

Run like this:

openapi-generator-cli generate \
  -i spec.yaml \
  -g dart \
  -o output \
  --additional-properties=useOptional=true,patchOnly=true

Will produce output like this:

// POST request - regular nullable
class CreateUserRequest {
  String? email;
  String? name;
}

// PATCH request - uses Optional with nullable inner type
class UpdateUserRequest {
  Optional<String?> email;
  Optional<String?> name;
}

// Usage
final update = UpdateUserRequest(
  email: Optional.present('eirikb@eirikb.no'),  // Do update
  name: Optional.absent(),  // Don't update
);

Without the patchOnly=true flag all fields will be Optional.

Thanks :)