GraphQL是什么?
GraphQL 是一种用于 API 的查询语言(区别于RESTful API),可以使得客户端能够准确地获得它需要的数据,没有任何冗余,最早是由Facebook在2012年使用,2015年进行了开源。
我使用下来的感受是,在iOS端做数据请求的时候,更像是在服务端用查询语句查询数据库,需要什么样的返回结果,都可以通过修改语句来实现。
优点:
1.请求数据无冗余。向你的 API 发出一个 GraphQL 请求就能准确获得你想要的数据,请求的数据都可由客户端控制的,返回的结果都是可预测的结果。
2.获取多个资源只用一个请求。REST API 请求多个资源时得需请求多个 API,而 GraphQL 可以通过一次请求就获取你所需的数据。
缺点:
1.使用 GraphQL 的APP还不是很常见,网上相关的技术讨论不多,遇到问题了需要自己花时间摸索。增加了学习时间成本以及其他人的接手成本。
2.使用需要集成三方框架,例如Apollo、SwiftGraphQL、GraphQLiOS(Objective-C使用)等。
3.需要由客户端来完成请求数据的语句,而不是简单的向API传递参数。
GraphQL官方文档:https://graphql.cn
Apollo是什么?
Apollo是一个GraphQL官方推荐的第三方工具,方便用户集成使用GraphQL。
Apollo官方文档:https://www.apollographql.com/docs
集成方法:
集成Apollo:
通过CocoaPods去集成Apollo(也可以通过Swift Package Manager、Carthage等其他方式集成,可参考Apollo官方文档)
在podfile文件中中添加 pod "Apollo",然后pod install,把Apollo相关的库集成到项目中。
下载schema文件
schema文件是从服务端下载下来的模版,用来校验客户端的请求。
2.在项目TARGETS的Build Phases栏目下
按截图顺序点击加号,选择 New Run Script Phase。
把名称修改为Apollo CLI,并移动到Compile Sources上面。
在Apollo CLI中复制粘贴下面这段代码,用来下载服务器的schema.json文件(实际使用时,地址改成自己的服务器地址)。
SCRIPT_PATH="${PODS_ROOT}/Apollo/scripts"
cd "${SRCROOT}/${TARGET_NAME}"
"${SCRIPT_PATH}"/run-bundled-codegen.sh schema:download --endpoint="https://n1kqy.sse.codesandbox.io/"
然后编译项目,会生成一个schema.json 文件。把这个文件Add Files 到你的项目中,之后要把这个文件,和后面要说的.graphql文件,还有最后生成的API.swift文件放在同一项目的目录下(不是有.xcodeproj和.xcworkspace的目录)。
这个schema文件是从你的服务器或者Apollo Studio Sandbox下载的(上面脚本里的地址就是这个方式,Sandbox是个在线调试工具,地址:https://n1kqy.sse.codesandbox.io/
)。schema是服务器上所有的可用的查询语句和数据类型的模版,相当于保存在客户端的一个协议。通过这个Apollo会校验这个请求是否可行。
创建.graghql文件
.graghql文件是用来放置请求语句的文件。
在Xcode里,新建一个空文件模板,命名为 LaunchList.graphql,将其保存在与schema.json文件相同的级别目录,将请求语句放在此文件里。
下面这个是sandbox的测试语句,复制到 LaunchList.graphql中:
query LaunchList {
launches {
cursor
hasMore
launches {
id
site
}
}
}
生成API.swift文件
在刚刚添加脚本的地方把最后一行注释掉(下载完schema后就不需要了),换成下面一段生成API的代码。
"${SCRIPT_PATH}"/run-bundled-codegen.sh codegen:generate --target=swift --includes=./**/*.graphql --localSchemaFile="schema.json" API.swift
然后编译项目,编译之后会生成一个API.swift文件,把它拖到Xcode中勾选Add to target。现在目录中就会有schema、LaunchList、API这三个文件了。
打开API.swift文件,会看到里面的内容和LaunchList中的请求语句是匹配的。如果在LaunchList.graphql中删除id属性,再次编译,API.swift文件里的id也会不见。这样Apollo就集成好了。
使用方法:
用下面这段代码,就可以进行数据请求了。
class Network {
static let shared = Network()
private(set) lazy var apollo = ApolloClient(url: URL(string: "https://n1kqy.sse.codesandbox.io/")!)
}
Network.shared.apollo.fetch(query: LaunchListQuery()) { result in
switch result {
case .success(let graphQLResult):
print("Success! Result: \(graphQLResult)")
case .failure(let error):
print("Failure! Error: \(error)")
}
}
实际使用的时候要把地址换成自己服务器,LaunchList.graphql中的语句按自己的需要修改。API文件里的内容不需要修改,每次运行都会根据.graphql和schema自动更新的。
这样,就完成了GraphQL和Apollo的简单配置和使用,更多的操作可以参照官方文档。
GraphQL官方文档:https://graphql.cn
Apollo官方文档:https://www.apollographql.com/docs