本文是GraphQL Advent Calendar 2020的第9天。
在上一篇文章中,@ shinnoki的2021 GraphQL代码生成器将使用TypedDocumentNode。
不需要GraphQL客户端库
GraphQL通常通过在HTTP上交换JSON来实现。
换句话说,您要做的就是讲HTTP和解析JSON。
取决于语言,不使用库就可以实现这些功能。
GraphQL客户端库主要用于缓存管理。
换句话说,对于很少使用缓存的应用程序几乎不需要GraphQL客户端。
GraphQL操作环境
的TypeScript代码生成
我说我不需要客户端,但是我想要一个与响应类型相对应的codegen。
这里以使用最多工具的TypeScript为例。
GraphQL提供了一个类型函数,可以根据GraphQL模式和操作(查询,变异,订阅,片段)确定类型。
1 2 3 4 5 6 7 8 | type Query { me: User! } type User { id: ID! name: String! } |
有一个名为
,
的架构
1 2 3 | query { me { name } } |
给定名为
的操作,响应类型在TypeScript中如下:
1 2 3 | interface Data { me: { name: string } } |
您可以按以下方式使用它。
1 2 | const res = await fetch("/graphql", {method: "POST", body: JSON.stringify({query: "query { me { name } }"})}); const data: Data = (await res.json()).data; |
尽管不需要
客户端,但是能够从操作(
对于TypeScript,这是graphql-codegen的typescript操作。
https://graphql-code-generator.com/docs/plugins/typescript-operations
Swift情况下GraphQL操作的代码生成
Swift似乎有两个代码生成器:
- https://github.com/apollographql/apollo-ios
- https://github.com/Shopify/graphql_swift_gen
由apollo-ios生成的代码是基于apollo的,如果不使用apollo的功能,我不会很高兴。
graphql_swift_gen似乎是为模式而不是为操作(查询,变异,订阅,片段)生成的。
GraphQL无法从类型中受益,因为响应会根据客户端操作的内容而变化。
在上一个示例中,
1 2 3 4 5 6 7 8 | type Query { me: User! } type User { id: ID! name: String! } |
即使您生成的类型直接与定义
,
1 2 3 4 5 6 7 8 | interface Query { me: User } interface User { id: string name: string } |
并非此
1 2 3 | query { me { name } } |
必须为
之类的操作生成它。
因此,我将graphql-codegen-swift-operations作为GraphQL Codegen的快速和操作插件??。
https://github.com/mtsmfm/graphql-codegen-swift-operations
graphql-codegen-swift-operations
有关特定的用法示例,请参阅https://github.com/mtsmfm/graphql-codegen-swift-operations/tree/master/swift-test-project。
首先,根据GraphQL Codegen教程进行设置。
https://graphql-code-generator.com/docs/getting-started/installation
接下来,
使用
1 2 3 4 5 | schema: ./schema.graphql documents: 'graphql/*.graphql' generates: Sources/app/generated.swift: - '@mtsmfm/graphql-codegen-swift-operations' |
https://github.com/mtsmfm/graphql-codegen-swift-operations/blob/master/swift-test-project/codegen.yml
之后,进行写操作。
1 2 3 | query AppQuery { ... } |
https://github.com/mtsmfm/graphql-codegen-swift-operations/blob/master/swift-test-project/graphql/query.graphql
运行
和
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | class AppQuery: Decodable { let data: Data?; let errors: Errors?; public static let operationDefinition: String = """ query AppQuery { ... } """ private enum CodingKeys: String, CodingKey { case data case errors } required init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) self.data = try container.decode(Data.self, forKey: .data) self.errors = try container.decodeIfPresent(Errors.self, forKey: .errors) } struct Data: Decodable { let organizations: [Internal_1_Organizations] ... } } |
https://github.com/mtsmfm/graphql-codegen-swift-operations/blob/master/swift-test-project/Sources/app/generation.swift
之后,可以将
1 2 3 4 5 6 7 8 9 10 11 12 13 | let client = SynchronousHTTPClient() do { let decoder = JSONDecoder() let data = try client.post(url: "http://localhost:4000/graphql", json: ["query": AppQuery.operationDefinition]) let result = try decoder.decode(AppQuery.self, from: data) if let data = result.data { for org in data.organizations { print(org as Any) } } } catch let error { ... } |
摘要
当点击
GraphQL时,您可能经常会从客户端库选择中输入内容,但是如果您记住,只要一开始点击它就不是必需的,那么您可能会看到不同的观点。
另外,在创建GraphQL Codegen插件时,
考虑到
似乎很好。