提问者:小点点

带有变量字段名的GraphQL类型


我试图将restcountries.com公开为GraphQLAPI。然而,我正在努力找出在GraphQL中创建类型定义以显示字段name. nativeName的最佳方法。

例如:如果您发送请求以获取有关加拿大等国家/地区的信息(GEThttps://restcountries.com/v3.1/alpha/ca),那么我们将得到如下响应:

"name": {
    "common": "Canada",
    "official": "Canada",
    "nativeName": {
        "eng": {
            "official": "Canada",
            "common": "Canada"
        },
        "fra": {
            "official": "Canada",
            "common": "Canada"
        }
    }
}

正如您在上面的响应中看到的,nativeName字段是一个具有两个内部字段engfra的对象。但是,如果我发送请求以获取另一个国家,例如芬兰(GEThttps://restcountries.com/v3.1/alpha/fi),响应将如下所示:

"name": {
    "common": "Finland",
    "official": "Republic of Finland",
    "nativeName": {
        "fin": {
            "official": "Suomen tasavalta",
            "common": "Suomi"
        },
        "swe": {
            "official": "Republiken Finland",
            "common": "Finland"
        }
    }
}

但是这一次,对于芬兰来说,nativeName有不同的字段finswe。换句话说,nativeName的内部字段会根据我们查询的国家/地区而变化。

那么,如何在GraphQLAPI中创建适当的typeDefs和解析器来支持这种情况,字段名称不可预测?到目前为止,这是我的typeDef,但我不知道如何为nativeName创建类型。

type Query {
    all: [Country!]!
}

type Country {
    name: CountryName!
}

type CountryName {
    common: String!
    official: String!
    nativeName: ... # I have no idea how to map nativeName
}

有没有办法在此类型变量中创建一个字段名?有人能提出一种方法来使用nativeName以及解析器的外观来完成这个typeDef吗?


共1个答案

匿名用户

这是一个常见的问题,您通常可以在“GraphQL Map”下找到它,例如这里。GraphQL中不能有动态字段。

现在你应该问问自己保持响应的原始形状有多重要。如果你不关心形状,GraphQL教条的方法是简单地返回一个列表:

type NativeName {
  lang: String!
  official: String 
  common: String
}

type CountryName {
  nativeName: [NativeName!]!
}

你的反应形状当然会改变。你的解析器可能是:

resolve(parent) {
  return Object.entries(parent.nativeName).map(([lang, rest]) => ({ lang, ...rest }));
}

如果您关心结果形状并且希望它尽可能接近原始形状,您可以按照大多数问题中提出的方式(如上所述)并使用JSON标量。尽管你失去了打字。

最后一个完全疯狂的方法:三位数的语言代码是有限的。您可以将它们中的每一个添加到一个对象中:

type NativeName {
  official: String 
  common: String
}

type NativeNameMap {
  afr: NativeName
  ain: NativeName
  aka: NativeName
  ...
}

type CountryName {
  nativeName: NativeNameMap
}

这听起来很疯狂,但是如果调用者提前知道将返回哪些语言,这可能是可行的。

相关问题