适用于iOS应用的GraphQL

编写iOS应用的典型方法

大多数现代移动应用程序只是JSON的漂亮表示形式-新闻订阅源,实时比分,即时通讯程序等。 通常,应用程序执行对REST端点的请求,接收JSON响应,将其转换为模型对象,最后将其显示在屏幕上。

iOS开发人员已经对这种方法感到满意了几年,因此现在有许多库,API和技术可用来构建此类应用程序。 但是感觉应该有一些改进的空间。 让我们找出弱点并考虑更好的解决方案。

REST怎么了

当iOS开发人员开始使用基于网络的功能时,通常会为他们提供一个现有的服务器端点,并希望有详尽的文档。 如果API针对移动客户端进行了优化,这始终是个好消息,但通常它只是服务器模型的一种表示形式。 问题在于应用程序通常需要的数据集与端点提供的数据略有不同。

假设我们正在构建一个GitHub团队浏览器,我们需要显示团队成员姓名列表以及他们的仓库名称,但是只有一个端点可以返回团队成员的完整信息以及ID。回购。 当然,我们可以要求后端团队引入新的端点或特殊参数,以仅获取对象或字段的子集:

  GET / members / 1213?listPreview = true 
  GET / membersAndRepos / 1213 

但这不是一个好的解决方案,因为:

  • 后端团队可能不可用;
  • 实现,测试和记录更多端点需要花费时间;
  • 应用需求可能会发生变化,因此这些添加将变得多余。

因此,自然必须发生的事情是在响应中下载不必要的数据并执行过多的请求。 如果客户端应用程序有一种很好的方法来指定所需的数据怎么办?

什么是GraphQL以及为什么很酷

GraphQL是使之成为可能的方法。 根据官方网站的说法,“ GraphQL是API的查询语言,并且是服务器端运行时,用于通过使用为数据定义的类型系统执行查询。 GraphQL不受任何特定数据库或存储引擎的束缚,而是由您现有的代码和数据支持。”

GraphQL于2012年出生于Facebook。他们的移动团队正在研究新的提要,当时他们意识到现有技术远不适合移动应用程序-那时互联网连接速度很慢,因此优化查询将大大改善用户体验。

在内部成功之后,该团队于2015年开源了GraphQL。现在GraphQL是RFC规范,并且有多种语言的实现。

除了Facebook本身,一些大公司已经引入了GraphQL API:GitHub和Shopify。

顾名思义,GraphQL是图形的“查询语言”。 由于大多数现代应用程序内部的数据都可以表示为图形,因此GraphQL是一种便捷的解决方案。

关于GraphQL的最神奇的部分是它的简单流程:

  1. 描述您的数据。
  2. 询问您想要什么。
  3. 获得可预测的结果。

描述数据

每个GraphQL服务都有一个架构-服务器上可用数据的蓝图。 强大的类型是GraphQL模式特别酷的地方。 此外, schema.json文件的作用类似于服务器的文档。

继续我们的repos示例,我们可以有一个这样的模式:

 输入用户{ 
名称:字符串!
avatarUrl:字符串
贡献的资料库:[资料库]!
}

索取资料

一旦知道服务器能够提供什么数据,就可以开始发送查询。 只需一个端点-它应该处理您的所有请求。

查询类似于JSON:

  { 
观众{
名称
paidRepository {
名称
}
}
}

您仅指定要在应用程序中进一步使用的那些字段。 除了参数和变量之类的基本功能外,查询还可以由别名,片段,指令和其他有趣的东西提供支持:

 查询成员($ login:String!){ 
用户(登录:$ login){
...用户详细信息
}
}
 用户{上的UserDetails片段 
名称
avatarUrl
allowedRepositories(first:100){
...回购详情
}
}

获得结果

如下所示,结果的形状与查询的形状完全相同。 因此,您始终可以获得预期的结果:

  { 
“数据”:{
“查看者”:{
“ name”:“ John Smith”,
“ contributedRepositories”:[
{
“名称”:“忍者工具”
},
{
“ name”:“ amazing-graphql”
}
]
}
}
}

与传统的REST方法相比,有几个优点:

  • 一个请求合并多个API调用;
  • 响应是整个应用程序图的子图;
  • 服务器的强类型导致客户端上的强类型;
  • 响应是JSON格式的,很容易解析并转换为模型。

所有这些都改善了开发人员和用户的体验。

如何使GraphQL在iOS上工作

iOS不支持开箱即用的GraphQL。 不幸的是,Facebook尚未在iOS上发布任何可与GraphQL一起使用的库。 因此,我们只能依靠第三方实现,也可以自己完成。

理想情况下,我们希望使用强类型(GraphQL模式→Swift模型),自动序列化和一些缓存。

有三种可能的方法:

  1. 天真—使用查询生成器库手动硬编码或编写请求,然后使用NSJSONSerialization,多个if let和用于缓存的数据层。
  2. 面向Web — React Native + Relay —如果您熟悉JS和前端开发。
  3. 本机— Apollo iOS。

阿波罗iOS

Apollo iOS是用于本机iOS应用程序的开源GraphQL客户端,以Swift编写并包装在Pod中。 它具有强大的类型和内置的缓存。 并且它与Xcode很好地集成在一起。 它是如何工作的?

首先,Apollo根据下载的架构和.graphql文件为您的GraphQL查询生成Swift类,并为响应生成Swift结构。 所有类型都放置在API.swift文件中。 这是通过自定义Xcode构建阶段自动完成的。

当您需要对GraphQL服务器进行查询时,只需构造一个获取请求对象,然后将其传递给ApolloClient并接收一个结构即可。 阿波罗(Apollo)还支持突变-它们与获取一样容易。 序列化是自动执行的,因此您无需处理JSON解析,传递字典和手动强制转换的工作。

此外,Apollo使用“相同路径=相同对象”原理缓存响应。 您也可以指定自己的缓存ID。 随着进一步的查询和变异的执行,缓存将保持最新状态。

另一个不错的功能是观看。 它类似于提取,但是除了接收初始响应外,每次更改缓存中的相应数据时,都会调用结果处理程序。

总之,Apollo提供了在GraphQL支持的后端上构建本机iOS应用所需的一切。

摘要

现在,当我们知道有一种编写与GraphQL API进行通信的本机应用程序的好方法时,让我们回顾一下Apollo + GraphQL方法的所有优缺点。

我认为,杀手级的功能是:

  • 将多个网络请求合并为一个;
  • 仅指定您感兴趣的数据。

这些属性导致更少的请求和更小的有效负载,可以极大地改善用户体验。

其他优点是:

  • 客户端开发人员可以控制发送什么数据;
  • 静态类型安全:从服务器到应用程序用户界面;
  • 好的工具(例如,用于探究GraphQL API的GraphiQL);
  • 明亮的社区。

当然,有一些缺点:

  • 不是灵丹妙药,您仍然需要REST,例如,下载资源或上传文件;
  • 需要时间来学习和采用;
  • iOS上没有开箱即用的支持;
  • 无法将自定义代码(变压器)注入映射过程;
  • Xcode代码生成中的一些故障。

总体而言,GraphQL是一项强大的技术,我们Castle公司很高兴能够在我们的移动应用程序中使用它。

Interesting Posts