-
Notifications
You must be signed in to change notification settings - Fork 86
Description
Description
When generating sealed classes from OpenAPI schemas with oneOf, swagger_parser correctly renames fields that are Dart keywords (e.g., required → requiredValue) in the base interface classes and adds the proper field mapping annotation (@MappableField(key: 'required') for dart_mappable or @JsonKey(name: 'required') for json_serializable). However, swagger_parser fails to add these field mapping annotations in the sealed class implementations.
This causes the serializer to use the Dart field name (requiredValue) instead of the original JSON field name (required) that the server expects, resulting in API requests being rejected or fields being ignored by the server.
Environment
- swagger_parser version: swagger_parser: ^1.37.0
- Dart SDK version: Dart 3.11.0 (build 3.11.0-12.0.dev) • DevTools 2.51.0
- Serializer:
dart_mappableandjson_serializable(tested and confirmed on both) - OpenAPI version: 3.0
Setup
OpenAPI Schema
components:
schemas:
OfferPutRequest:
type: object
properties:
subsections:
type: array
items:
oneOf:
- $ref: "#/components/schemas/OfferCheckboxPostRequest"
- $ref: "#/components/schemas/OfferTextFieldPostRequest"
OfferCheckboxPostRequest:
type: object
description: Represents a request to create a new checkbox field in an offer
properties:
type:
type: string
title:
type: string
customerChecked:
type: boolean
required:
type: boolean
required:
- customerChecked
- required
- title
- type
OfferTextFieldPostRequest:
type: object
properties:
type:
type: string
title:
type: string
customerResponse:
type: string
required:
type: boolean
required:
- required
- title
- typeConfiguration (build.yaml)
targets:
$default:
builders:
swagger_parser:
options:
schema_url: path/to/api-docs.yaml
output_directory: lib/api
json_serializer: dart_mappable
enums_to_json: true
unknown_enum_value: falseCurrent Behavior
Generated base class (CORRECT ✓)
offer_checkbox_post_request.dart:
@MappableClass()
class OfferCheckboxPostRequest {
const OfferCheckboxPostRequest({
required this.type,
required this.title,
required this.customerChecked,
required this.requiredValue,
});
final String type;
final String title;
final bool customerChecked;
@MappableField(key: 'required') // ✓ Correct mapping
final bool requiredValue;
}When this class serializes to JSON, it correctly produces:
{
"type": "checkbox",
"title": "Accept terms",
"customerChecked": false,
"required": true // ✓ Correct field name
}Generated sealed class (INCORRECT ✗)
offer_post_request_subsections_sealed.dart:
@MappableClass()
class OfferPostRequestSubsectionsSealedOfferCheckboxPostRequest
extends OfferPostRequestSubsectionsSealed
implements OfferCheckboxPostRequest {
@override
final String type;
@override
final String title;
@override
final bool customerChecked;
@override
final bool requiredValue; // ✗ Missing @MappableField(key: 'required')
const OfferPostRequestSubsectionsSealedOfferCheckboxPostRequest({
required this.type,
required this.title,
required this.customerChecked,
required this.requiredValue,
});
// ... rest of implementation
}When the sealed class serializes to JSON, it produces:
{
"type": "checkbox",
"title": "Accept terms",
"customerChecked": false,
"requiredValue": true // ✗ Wrong field name!
}Expected Behavior
The sealed class should preserve the field name mapping:
@MappableClass()
class OfferPostRequestSubsectionsSealedOfferCheckboxPostRequest
extends OfferPostRequestSubsectionsSealed
implements OfferCheckboxPostRequest {
@override
final String type;
@override
final String title;
@override
final bool customerChecked;
@override
@MappableField(key: 'required') // ✓ Should be present
final bool requiredValue;
// ... rest of implementation
}And the correct JSON:
{
"type": "checkbox",
"title": "Accept terms",
"customerChecked": false,
"required": true // ✓ Correct field name
}