[Dart] Add UInt8List support, allowing for type:string format:binary definitions
Summary
tl;dr UInt8List support, which Dart-Dio has, has been added to the regular Dart2 generator.
Fixes #12161.
Details
Changes to the Generators:
To support UInt8List in the generator, Typed Data imports had to be added. Additionally, some OpenAPI data types have been switched to Uint8List.
- [AbstractDartCodeGen.java]: added
Uint8List/dart:typed_datato the imports. - [AbstractDartCodeGen.java]: Changed
typeMappingof {file, binary} toUint8Listaway fromMultiPartFile - [AbstractDartCodeGen.java]: Copied Multipart/Uint8list differentiation in
postProcessOperationsWithModelsfrom DartDioClientCodegen.java - [dart2/apilib.mustache]: Added
import 'dart:typed_data';
Changes to the API classes
To support Uint8List in the generated API output, parts of the *api.dart files had to be refactored. Presently Dart2 relies on passing utf8 decoded response byte strings through its API calls, but this leads to errors because not all response objects are json strings. To handle this, I refactored many of the calls to take Uint8List's straight from response.bodyBytes. Decoding into a String object doesn't happen until it needs to, which is right before passing the object down into the Json Decoding section.
- [api_client.dart]: deserialize and deserializeAsync now take Uint8List as their default input
- [api_helper.dart]: removed _decodeBodyBytes in favor of just using
response.bodyBytes - [api_helper.dart]: added
decodeErrormethod to deal with the byte response, which decodes the resposne into a utf-8 String.
To confirm this change, use the following specfile:
specfile
openapi: 3.0.3
info:
version: "1.1"
title: Dart Uint8list Demo
servers:
- url: "localhost"
variables:
host:
default: localhost
paths:
/getData:
get:
operationId: GetData
description: "Should return a Uint8List of bytes"
responses:
"200":
description: Binary data
content:
application/octet-stream:
schema:
type: string
format: binary
put:
operationId: PutData
description: "Should push a Multipart File"
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
fileContent:
type: string
format: binary
responses:
"200":
description: OK
content:
application/json:
schema:
type: string
/item:
get:
operationId: GetItem
description: "Should return an Item"
responses:
"200":
description: items
content:
application/json:
schema:
$ref: "#components/schemas/item"
components:
schemas:
Item:
type: object
description: "Some json thing"
required:
- intField
- doubleField
- stringField
- dateField
- timeField
- dateTimeField
- boolField
- b64Field
- intArrayField
properties:
intField:
type: integer
format: int32
doubleField:
type: number
format: float
stringField:
type: string
dateField:
type: string
format: date
timeField:
type: string
format: time
dateTimeField:
type: string
format: date-time
boolField:
type: boolean
b64Field:
type: string
format: byte
intArrayField:
type: array
items:
type: integer
format: int32
PR checklist
- [x] Read the contribution guidelines.
- [x] 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.
- [x] Run the following to build the project and update samples:
- [x] File the PR against the correct branch:
master(6.1.0) (minor release - breaking changes with fallbacks),7.0.x(breaking changes without fallbacks) - [x] If your PR is targeting a particular programming language, @mention the technical committee members, so they are more likely to review the pull request.
@jaumard @josh-burton @amondnet @sbu-WBT @kuhnroyal @agilob @ahmednfwela
When I get home I'll try to fix it, but I didn't touch any of those files by hand. I only ran the generate samples script. I didn't even open these in my editor.
@kuhnroyal @wing328 Can you check why the tests were passing here when there was a compile error for the generated code?
@0xNF did you make any changes in the java files? I can't see them in the PR
The Java changes seem to have gotten lost. Sorry this PR is kinda messy. I'm flipping between too many branches rn.
@kuhnroyal @wing328 Can you check why the tests were passing here when there was a compile error for the generated code?
The test did run and passed. Does it has anything to do with Dart version?
- uses: dart-lang/setup-dart@v1
with:
sdk: 2.14.0
That's what we use in the CI.
dart 2 uses 2.12 in the generated code, which 2.14 should be able to run
Can you please paste the compilation error here as well? I'll try to repeat that locally.
It's probably because I force pushed the update to my own branch, and the tests didn't re-run here.
It's probably because I force pushed the update to my own branch, and the tests didn't re-run here.
To trigger the run, please update the samples and the Github action (dart job) will run again.
Should I be regenerating all samples? Up til now I've just been regenerating the relevant samples for my changes (Dart). But then the CI complains.
yes please update the samples as the CI fails: https://github.com/OpenAPITools/openapi-generator/actions/runs/3086648029/jobs/4991237644
@0xNF @wing328 Is there any movement on this? It looks like this PR is functionally ready to land. Just needing some clean-up.
Currently, I'm facing an issue around this as passing a UInt8List to a generated API endpoint causes the following error:
DioError [DioErrorType.other]: Bad state: No serializer for 'Uint8List'.
Relevant Code (Generated API's model.dart):
yield serializers.serialize(
object.appBinaryData,
specifiedType: const FullType(Uint8List),
);
@zmoshansky this PR is for dart generator, and it seems like you are using the dart-dio generator, please create a new Issue with reproducible sample