Apollo 与 GraphQL 项目实战中遇到的问题

GraphQL重新定义了接口查询,不过现在使用上还是有许多问题,因为最近的项目中用到了,现将错误记录下来。

使用一:生成schema.json文件

生成schema文件需要使用 apollo-codegen,使用它需要安装node环境:

npm install -g apollo-codegen

如果未安装npm, 那还需要安装npm
转换schema.json文件:

apollo-codegen download-schema server-url --output schema.json


错误一 : Did you forget to add custom type adapter?

# 有一个新的 字段 DateTime
Representation of date and time in "Y-m-d H:i:s" format
scalar DateTime

后台定义了一个新的标量类型DateTime, 当使用Apollo自动生成对象类型时,会在package/type/下生成一个CustomType对象, 里面会自动生成你定义好的自定义标量,但是Apollo还找不到你定义好的自定义标量,需要将其告诉Apollo Client

步骤:
1、 添加类型告诉Apollo , 在使用apply plugin: 'com.apollographql.android'build.gradle中最下面添加(层级与android{}相同):

apollo {
    customTypeMapping = [
            "DateTime"      : "java.util.Date",
    ]
}

2、注册类型到Apollo Client

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss", Locale.ENGLISH);
CustomTypeAdapter<Date> dateCustomTypeAdapter = new CustomTypeAdapter<Date>() {
    @Override
    public Date decode(CustomTypeValue value) {
        try {
            return simpleDateFormat.parse(value.value.toString());
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }
    @Override
    public CustomTypeValue encode(Date value) {
        return new CustomTypeValue.GraphQLString(simpleDateFormat.format(value));
    }
};
// 初始化ApolloClient
mApolloClient = ApolloClient.builder()
        .serverUrl(getHost(hostType))
        .okHttpClient(getOkHttpClient())
        .addCustomTypeAdapter(CustomType.DATETIME, dateCustomTypeAdapter)
        .build();

到这里,就可以将你的2019-04-16 00:00:00转换成Date类型。

错误二 : Apollo对象名字一样

假设你的schema.json文件中,后台定义好的对象有一个是这样的

// Prop 对象定义
{
          "kind": "OBJECT",
          "name": "Prop",
          "description": null,
          "fields": [
           {
              "name": "country",
              "description": null,
              "args": [],
              "type": {
                "kind": "LIST",
                "name": null,
                "ofType": {
                  "kind": "OBJECT",
                  "name": "CountryLabelValue",
                  "ofType": null
                }
              },
              "isDeprecated": false,
              "deprecationReason": null
            }
        ]
....
}

// CountryLabelValue 对象
{
  "kind": "OBJECT",
  "name": "CountryLabelValue",
  "description": "Country Value Label",
  "fields": [
    {
      "name": "value",
      "description": null,
      "args": [],
      "type": {
        "kind": "NON_NULL",
        "name": null,
        "ofType": {
          "kind": "ENUM",
          "name": "Country",
          "ofType": null
        }
      },
      "isDeprecated": false,
      "deprecationReason": null
    }
  ]
}

聪明的你会发现,CountryLabelValue对象的名字是Country, 而CountryLableValue中又包含一个类型为ENUM类型的Country,导致Apollo在自动生成对象的时候,找不到该对象, 在自动生成的对象中,你可以找到如下错误:

writer.writeList($responseFields[2], propertyCountries, new ResponseWriter.ListWriter() {
  @Override
  public void write(List items, ResponseWriter.ListItemWriter listItemWriter) {
    for (Object item : items) {
      listItemWriter.writeObject(((Country) item).rawValue());
    }
  }
});

这个地方的Country其实应该List类型的CountryLabelValue, 但是同一个对象中包含的其他对象名字与它冲突了,搜索Apollo中的issue发现有人遇到了同样的问题:
https://github.com/apollographql/apollo-android/issues/1156
具体的解决方法是添加别名:

prop{
        gateway{
            label
            value
        }
       country {
                label
                value
        }
        payment_status{
            label
            value
        }
}

修改为:

prop{
    gateway{
        label
        value
    }
    propertyCountries : country {
            label
            value
    }
    payment_status{
        label
        value
    }
}

这样就不会在编译的时候报错了,而最后生成的对象变成了这样:

writer.writeList($responseFields[2], propertyCountries, new ResponseWriter.ListWriter() {
  @Override
  public void write(List items, ResponseWriter.ListItemWriter listItemWriter) {
    for (Object item : items) {
      listItemWriter.writeObject(((PropertyCountry) item).marshaller());
    }
  }
});

字段变成了你设置的别名

项目实战待续~
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,546评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,224评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,911评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,737评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,753评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,598评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,338评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,249评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,696评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,888评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,013评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,731评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,348评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,929评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,048评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,203评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,960评论 2 355