在动态类型语言中的GraphQL客户端
当编写使用GraphQL API的客户端代码时,在静态类型语言中,使用codegen的方法非常有效。原因是可以从已经存在的GraphQL Schema中免费获取类型信息。
另一方面,如果像JavaScript或Ruby这样的动态类型语言成为GraphQL API的client,该如何处理呢?即使在这种情况下,通过codegen生成类并映射响应的方法可能会有一定效果(例如,类的存在可能会提供一些IDE的支持,这还没有实际尝试过),但至少不能期望获得像静态类型语言那样的好处。
在动态类型语言的情况下,更倾向于充分发挥其特性,暂且抛弃 codegen 的繁琐(虽然实质上是免费的,但是哈哈),而更注重方便性。如果是在JavaScript中,通常可以使用普通的object;如果是在Ruby中,可以使用OpenStruct。另外,只要程序员足够相信它是一种类型即可。这就是与静态类型语言的思维方式不同之处。
以下是在Ruby中调用GraphQL API的代码(只给出大意)。
class FooRepository
FOO_QUERY = <<~EOS
query foo($id: ID!) {
foo(id: $id) {
bar {
baz
}
}
}
EOS
def self.find(id)
res = Faraday.post('.../graphql', { query: FOO_QUERY, variables: { id: id } })
# このへんでエラーハンドリングとかする
# OpenStructにマッピングする
# 正確には再帰的にやる必要がある
foo = OpenStruct.new(JSON.parse(res.body)['data'])
# 振る舞いをmixinすることもできる
foo.extend(SomeModule)
foo
end
end
在上述的代码中,GraphQL查询位于方法代码的上方,这样可以更清楚地了解从该方法返回什么类型的对象。在动态类型的语言中,如果程序员相信返回的是什么类型,那么这种程度的灵活性就足够了。
顺便说一句,在访问OpenStruct中不存在的键时,会返回nil,但现在有一个叫做OpenStruct::Strict的建议可以抛出错误而不返回nil(https://github.com/ruby/ruby/pull/3594)。作为GraphQL客户端,我认为这种行为更加方便使用,所以可以考虑在代码中引入这种类似的封装。
目前,對於 Web 前端開發來說,TypeScript是主流,同時Swift和Kotlin也成為了客戶端開發中靜態類型編程的時代,然而在服務器端,像Ruby (on Rails)等動態類型編程的語言仍然很受歡迎。因此,在進行 Server to Server 的 GraphQL API 請求時,可能會使用動態類型編程的語言來進行。在這種情況下,建議不要強行使用靜態類型編程的技巧,而是充分發揮動態類型編程語言的優勢來進行實作。