tazatechnology / openapi_spec

Dart based OpenAPI specification generator and parser
BSD 3-Clause "New" or "Revised" License
8 stars 5 forks source link

Null in enum not handled correctly #63

Open dickermoshe opened 6 months ago

dickermoshe commented 6 months ago
Details

``` components: schemas: AnyOfTest: anyOf: - type: string - $ref: '#/components/schemas/EnumString' - $ref: '#/components/schemas/EnumNullString' - $ref: '#/components/schemas/EnumNull' description: to test anyOf (string, enum string) EnumNull: enum: - null type: string EnumNullString: enum: - 'null' type: string EnumString: enum: - A - B type: string info: license: name: MIT title: Example version: 1.0.0 openapi: 3.0.1 paths: /person/display/{personId}: get: operationId: list parameters: - description: The id of the person to retrieve in: path name: personId required: true schema: type: string responses: '200': content: application/json: schema: $ref: '#/components/schemas/AnyOfTest' description: OK servers: - url: http://api.example.xyz/v1 ```

walsha2 commented 6 months ago
EnumNull:
  enum:
  - null
  type: string

I am not sure I follow, what does this even represent as a Dart class? How is this a proper enum definition?

I am not sure this edge case is even worth spending time coding up and protecting for... Unless you have a real world example that is not an edge case test scheme from OpenAPI repo?

dickermoshe commented 6 months ago

It's more common than you think. The example I posted is stupid, but this update in 3.1 added full support with the json schema which does

EnumNull:
  enum:
  - null
  - ice_cream
  - yogurt
  type: string

It used to be

EnumNull:
  enum:
  - ice_cream
  - yogurt
  type: string
  nullable: true

https://github.com/OAI/OpenAPI-Specification/issues/1900#issuecomment-485444377

dickermoshe commented 6 months ago

Proposal: swagger-parser add an unknown value that makes the api backwards compatible. So even if this isn't fixed, it will still wont throw when null is returned what do you think?

// coverage:ignore-file
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint, unused_import

import 'package:freezed_annotation/freezed_annotation.dart';

@JsonEnum()
enum Status {
  @JsonValue('available')
  available('available'),
  @JsonValue('pending')
  pending('pending'),
  @JsonValue('sold')
  sold('sold'),
  /// Default value for all unparsed values, allows backward compatibility when adding new values on the backend.
  $unknown(null);

  const Status(this.json);

  factory Status.fromJson(String json) => values.firstWhere(
        (e) => e.json == json,
        orElse: () => $unknown,
      );

  final String? json;
}
walsha2 commented 6 months ago

Ok so it just means that the enum itself is nullable, not that the individual enum value is null. I dont really like that spec definition.

There is a "simple" fix for this, I believe. I can take care of it.