【问题标题】:Flutter ferry custom scalar serializer "has non-dynamic type"Flutter 渡轮自定义标量序列化器“具有非动态类型”
【发布时间】:2021-09-04 10:42:55
【问题描述】:

我在使用 Flutter Ferry graphql 包中的自定义序列化程序时遇到了一点问题:

我完全使用了渡轮文档中的示例: https://ferrygraphql.com/docs/custom-scalars/#create-a-custom-serializer

但我在运行 builder_runner 时总是收到以下消息:

[SEVERE] built_value_generator:built_value on lib/schema.schema.gql.dart:
Error in BuiltValueGenerator for abstract class GDailyForecastInput implements Built<GDailyForecastInput, dynamic>.
Please make the following changes to use BuiltValue:

1. Make field dateStart have non-dynamic type. If you are already specifying a type, please make sure the type is correctly imported.
2. Make field dateEnd have non-dynamic type. If you are already specifying a type, please make sure the type is correctly imported.
[SEVERE] built_value_generator:built_value on lib/schema.schema.gql.dart:
Error in BuiltValueGenerator for abstract class GHourlyForecastInput implements Built<GHourlyForecastInput, dynamic>.
Please make the following changes to use BuiltValue:

1. Make field dateStart have non-dynamic type. If you are already specifying a type, please make sure the type is correctly imported.
2. Make field dateEnd have non-dynamic type. If you are already specifying a type, please make sure the type is correctly imported.

dateStart 和 dateEnd 是 Date 类型的查询输入值 这是我的类型覆盖: 类型覆盖: 日期: 名称日期 有人为什么会发生此错误吗? 实在想不通是什么问题

日期在我的 schema.graphql 文件中定义为标量:

"""A date string with format `Y-m-d`, e.g. `2011-05-23`."""
scalar Date

这是我的 build.yaml 文件:

targets:
  $default:
    builders:
      gql_build|schema_builder:
        enabled: true
        options:
          type_overrides:
            Date:
              name: Date
              
      gql_build|ast_builder:
        enabled: true
        options:
          type_overrides:
            Date:
              name: Date

      gql_build|data_builder:
        enabled: true
        options:
          type_overrides:
            Date:
              name: Date
          schema: appdemo|lib/schema.graphql

      gql_build|var_builder:
        enabled: true
        options:
          type_overrides:
            Date:
              name: Date
          schema: appdemo|lib/schema.graphql

      gql_build|serializer_builder:
        enabled: true
        options:
          schema: appdemo|lib/schema.graphql
          custom_serializers:
            - import: './serializers/date_serializer.dart'
              name: DateSerializer

      ferry_generator|req_builder:
        enabled: true
        options:
          type_overrides:
            Date:
              name: Date
          schema: appdemo|lib/schema.graphql

我已经尝试过调试。如果我将我的标量重命名为 DateTime 一切正常。 (我的schema.graphql 文件中还有一个标量DateTime。) 只有当我使用名称 Date 时才会收到此错误。

我错过了什么吗? 我是否需要在文档中的代码之外创建一个 dart Date 类并链接它左右?

【问题讨论】:

    标签: flutter dart built-value


    【解决方案1】:

    确保您还包括 data_builder、var_builder 和 req_builder 的 type_overrides。

    重要 为简洁起见,我们仅包含了上面的 schema_builder,但我们还需要为 data_builder、var_builder 和 req_builder 包含相同的 type_overrides 映射。有关详细信息,请参阅完整的 build.yaml 示例。

    例如:

    假设我有两个自定义标量,一个原始类型和一个非原始类型,

    schema.graphql:

    scalar Date #A datetime string in iso8601.
    scalar Metadata #A map with key string and value any.
    
    type Test {
      id: ID!
      date: Date!
      metadata: Metadata!
    }
    
    type Query {
      getTest(): Test!
    }
    

    date_serializer.dart:

    import 'package:built_value/serializer.dart';
    
    class DateSerializer implements PrimitiveSerializer<DateTime> {
      @override
      DateTime deserialize(
        Serializers serializers,
        Object serialized, {
        FullType specifiedType = FullType.unspecified,
      }) {
        assert(serialized is String,
            "DateSerializer expected 'String' but got ${serialized.runtimeType}");
        return DateTime.parse(serialized is String ? serialized : "");
      }
    
      @override
      Object serialize(
        Serializers serializers,
        DateTime date, {
        FullType specifiedType = FullType.unspecified,
      }) =>
          date.toUtc().toIso8601String();
    
      @override
      Iterable<Type> get types => [DateTime];
    
      @override
      String get wireName => "Date";
    }
    

    metadata_serializer.dart:

    import "package:gql_code_builder/src/serializers/json_serializer.dart";
    
    class MetadataSerializer extends JsonSerializer<Map<String, dynamic>> {
      @override
      Map<String, dynamic> fromJson(Map<String, dynamic> json) => json;
    
      @override
      Map<String, dynamic> toJson(Map<String, dynamic> map) => map;
    }
    
    

    build.yaml:

    targets:
      $default:
        builders:
          gql_build|schema_builder:
            enabled: true
            options:
              type_overrides:
                Metadata:
                  name: Map<String, dynamic>
                Date:
                  name: DateTime
          gql_build|ast_builder:
            enabled: true
    
          gql_build|data_builder:
            enabled: true
            options:
              schema: my_project|lib/schema.graphql
              type_overrides:
                Metadata:
                  name: Map<String, dynamic>
                Date:
                  name: DateTime
          gql_build|var_builder:
            enabled: true
            options:
              schema: my_project|lib/schema.graphql
              type_overrides:
                Metadata:
                  name: Map<String, dynamic>
                Date:
                  name: DateTime
          gql_build|serializer_builder:
            enabled: true
            options:
              schema: my_project|lib/schema.graphql
              custom_serializers:
                - import: 'path/to/metadata_serializer.dart'
                  name: MetadataSerializer
                - import: 'path/to/date_serializer.dart'
                  name: DateSerializer
    
          ferry_generator|req_builder:
            enabled: true
            options:
              schema: my_project|lib/schema.graphql
              type_overrides:
                Metadata:
                  name: Map<String, dynamic>
                Date:
                  name: DateTime
    

    构建后,您现在应该已覆盖两个标量,

    test.dart:

    client.request(request).first.then((response){
      print(response.data?.test.date.runtimeType);
      print(response.data?.test.metadata.runtimeType);
    })
    
    

    output:

    DateTime
    JsLinkedHashMap<String, dynamic>
    

    【讨论】:

    • 感谢@Carlie 抽出宝贵时间查看它。它无处不在。就像我写的那样,如果我将类型更改为 DateTime 它会起作用。 :)
    • 您介意展示一下您的build.yaml 的样子吗?
    • 不,当然不是。我已将其添加到我原来的问题中。谢谢
    • 我看到日期在dart:core 库中不是有效类型,请尝试将name: Date 替换为name: DateTime
    • 这行得通,但如果我想用新的自定义类型序列化它怎么办?我已经有了 DateTime(这是一个有时间的日期)。如果我只需要解析日期怎么办?或者换种说法:假设我有一个全新的类型,它没有任何对应的颤振类型?我认为这正是序列化程序的作用?
    猜你喜欢
    • 2018-07-05
    • 1970-01-01
    • 2015-02-05
    • 2020-02-15
    • 1970-01-01
    • 1970-01-01
    • 2017-07-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多