gql-dart / ferry

Stream-based strongly typed GraphQL client for Dart
https://ferrygraphql.com/
MIT License
593 stars 113 forks source link

Unable to Upload Multipart File with dio link #584

Open incrediblezayed opened 5 months ago

incrediblezayed commented 5 months ago

Hey, The file upload with http works fine but the dio has problem I'll put the details below:

Dependency Versions:

dio: ^5.4.1
ferry: ^0.16.0+1
ferry_generator: ^0.10.0
gql_dio_link: ^1.0.1+1

Serialiser Code:

class UploadSerializer extends PrimitiveSerializer<MultipartFile> {
  @override
  MultipartFile deserialize(
    Serializers serializers,
    Object serialized, {
    FullType specifiedType = FullType.unspecified,
  }) {
    assert(
      serialized is List<int>,
      "FileSerializer expected 'Uint8List' but got ${serialized.runtimeType}",
    );
    return MultipartFile.fromBytes(serialized as List<int>);
  }

  @override
  Object serialize(
    Serializers serializers,
    MultipartFile object, {
    FullType specifiedType = FullType.unspecified,
  }) =>
      object;

  @override
  Iterable<Type> get types => [MultipartFile];

  @override
  String get wireName => 'Upload';
}

build.yaml

targets:
  $default:
    sources:
      exclude:
        - lib/**/**.dart
    builders:
      ferry_generator|graphql_builder:
        enabled: true
        options:
          schema: com|lib/src/app/repository/graphql/schema.graphql
          type_overrides:
            JSON:
              name: JsonObject
              import: "package:built_value/json_object.dart"
            Upload:
              name: MultipartFile
              import: "package:dio/dio.dart"
      ferry_generator|serializer_builder:
        enabled: true
        options:
          schema: com|lib/src/app/repository/graphql/schema.graphql
          custom_serializers:
            - import: "package:built_value/src/json_object_serializer.dart"
              name: JsonObjectSerializer
            - import: "package:com/src/custom_serializers/upload_serializer.dart"
              name: UploadSerializer

Error:

LinkException(DioException [unknown]: null
              Error: type 'FormData' is not a subtype of type 'Map<dynamic, dynamic>' in type cast, #0      DioMixin.fetch.<anonymous closure> (package:dio/src/dio_mixin.dart:510:7)
              #1      _FutureListener.handleError (dart:async/future_impl.dart:180:22)
              #2      Future._propagateToListeners.handleError (dart:async/future_impl.dart:850:47)
              #3      Future._propagateToListeners (dart:async/future_impl.dart:871:13)
              #4      Future._completeError (dart:async/future_impl.dart:651:5)
              #5      _SyncCompleter._completeError (dart:async/future_impl.dart:63:12)
              #6      _Completer.completeError (dart:async/future_impl.dart:27:5)
              #7      Future.any.onError (dart:async/future.dart:613:45)
              #8      _RootZone.runBinary (dart:async/zone.dart:1666:54)
              #9      _FutureListener.handleError (dart:async/future_impl.dart:177:22)
              #10     Future._propagateToListeners.handleError (dart:async/future_impl.dart:850:47)
              #11     Future._propagateToListeners (dart:async/future_impl.dart:871:13)
              #12     Future._completeError (dart:async/future_impl.dart:651:5)
              #13     Future._asyncCompleteError.<anonymous closure> (dart:async/future_impl.dart:737:7)
              #14     _microtaskLoop (dart:async/schedule_microtask.dart:40:21)
              #15     _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5)
              ) 
knaeckeKami commented 5 months ago

You probably don't want to store the uploaded file in the graphql cache

bawahakim commented 4 months ago

What is the FormData type? Would be helpful to see the schema. If FormData is the scalar that you send to the backend, then you should replace Upload with FormData (both in the build.yaml and the serializer wire name).

I can confirm that uploading with Dio works