ios graphql_用于iOS开发的GraphQL

ios graphql

什么是GraphQL(入门) (What is GraphQL (A Primer))

GraphQL is a query language for APIs. It specifies the ways that a client can communicate with a server. If you are familiar with a REST API, you can think of this as an alternative. REST APIs are typically defined as a set of endpoints that represent resources with which you can perform CRUD operations via HTTP methods… For a blog app (like Medium) these resources may be Authors , Posts , Comments , etc. With GraphQL, resources are NOT defined by API endpoints, they are defined by a schema that is introspected by clients who will then formulate whatever queries they want as long as they are valid according to that schema.

GraphQL是API的查询语言。 它指定客户端与服务器通信的方式。 如果您熟悉REST API,则可以将其视为替代方法。 REST API通常定义为一组端点,这些端点表示可以通过HTTP方法执行CRUD操作的资源…对于博客应用(如Medium),这些资源可以是AuthorsPostsComments等。对于GraphQL而言,资源不是由API端点定义,它们是由客户自省的架构定义的,客户将根据所需的查询提出只要它们有效的查询。

Image for post
!?BUT WHAT DOES THAT EVEN MEAN!?
!但是那什至意味着什么呢?

If this just sounds like a bunch of jargon to you, I will attempt to simplify it: With REST, the API endpoints determine what data can be exchanged over the network. With a GraphQL endpoint, the client determines what data will be exchanged over the network, as long as its supported by the schema.

如果这听起来像是一句行话,我将尝试简化一下:使用REST, API端点确定可以通过网络交换哪些数据。 使用GraphQL端点, 客户端 可以确定将通过网络交换哪些数据,只要该数据受模式支持即可。

From a client perspective, GraphQL implementation goes as follows:

从客户端的角度来看,GraphQL实现如下:

  • Get the schema from the GraphQL API

    从GraphQL API获取架构
  • Introspect the schema to know what operations and types are available to you

    内省架构以了解可用的操作和类型
  • Build the desired queries for your client

    为客户建立所需的查询
  • Direct your queries at the GraphQL API endpoint.

    将查询定向到GraphQL API端点。

… More on this later.

……稍后再讨论。

为什么选择GraphQL? (Why GraphQL?)

Our apps are completely fine the way they are! Why would I want to change from using REST to GraphQL?

我们的应用程序完全一样! 为什么要从使用REST更改为GraphQL?

Well this argument is fair, there is a little bit of a learning curve with GraphQL… and you may not solve too many problems by using it over REST. But it does solve one set of problems exceptionally well:

好吧,这个说法很合理,GraphQL有点学习困难……您可能无法通过在REST上使用它来解决太多问题。 但这确实可以很好地解决一组问题:

更少的网络呼叫和“特殊端点” (Fewer Network Calls and “Special Endpoints”)

Most data models have relationships with one another, to bring back the blog example: Users may have Posts , Posts may have Comments, those comments will have associated Users, and it goes on and on. As iOS developers, we all run into the issue where we need to chain API requests to get all of the resources in order to populate a particular view. We hate this. We want to hit the network as few times as possible, it makes for cleaner, more performant code and a better user experience. A solution to this problem would be to constantly go back to your API authors and ask for “special” endpoints. This is where REST starts to break down. This “special” endpoint doesn’t necessarily represent any particular resource, but it represents a fine tuned response that a particular client will need. API authors may be reluctant to create these “special” endpoints because it detracts from the whole REST paradigm and can lead to some messy code on their end… but for performance reasons, we can usually force their hand.

大多数数据模型彼此之间都有关系,以博客示例为例: Users可能有PostsPosts可能有Comments ,这些评论将具有关联的Users ,并且这种关系一直持续下去。 作为iOS开发人员,我们都遇到了以下问题:我们需要链接API请求以获取所有资源,以填充特定视图。 我们讨厌这个。 我们希望尽可能少地访问网络,这可以使代码更整洁,性能更高,并提供更好的用户体验。 解决此问题的方法是不断地与您的API作者联系,并要求“特殊”端点。 这是REST开始崩溃的地方。 此“特殊”端点不一定代表任何特定资源,但代表特定客户端将需要的微调响应。 API作者可能不愿意创建这些“特殊”端点,因为它破坏了整个REST范式,并可能在其末端导致一些混乱的代码……但是出于性能方面的考虑,我们通常可以强迫他们。

With GraphQL the client can specify exactly what it wants in every request, nothing more, nothing less. The shape of the response will be the same as the shape of the request. This means:

借助GraphQL,客户端可以在每个请求中准确指定所需的内容,仅此而已。 响应的形状将与请求的形状相同。 这表示:

不再有对多个资源的链接请求。 (No more chained requests for multiple resources.)

没有更多未明确要求的无关数据,从而导致响应拥挤 (No more extraneous data that wasn’t explicitly asked for, crowding the response)

面向特殊端点的API开发人员不再来回 (No more back and forth with API devs for special endpoints)

GraphQL:详细信息 (GraphQL: The Details)

GraphQL supports three different kinds of operations

GraphQL支持三种不同类型的操作

Queries, which fetch data.

查询 ,用于获取数据。

Mutations, which (you guessed it!) mutate data.

突变 ,(您猜对了!)突变数据。

Subscriptions, which subscribe a client for realtime updates.

订阅 ,用于订阅客户端实时更新。

To execute any of these, you will have to formulate them using GraphQL Query Language.

要执行其中任何一个,您将必须使用GraphQL查询语言来制定它们。

Here is an example of a query, followed by an example of a mutation. To learn more about GraphQL Query Language syntax, check out the docs

这是一个查询示例,然后是一个突变示例。 要了解有关GraphQL查询语言语法的更多信息, 请查看文档

query HeroNameAndFriends {
hero {
name
friends {
name
}
}
}

The truth is, GraphQL shines the most over REST when fetching data via queries, but all CRUD operations are, of course supported by the GraphQL spec.

事实是,当通过查询获取数据时,GraphQL在REST上表现最为出色,但是GraphQL规范当然支持所有CRUD操作。

mutation CreateReviewForEpisode($ep: Episode!, $review: ReviewInput!) {
createReview(episode: $ep, review: $review) {
stars
commentary
}
}

If you’re looking at this type of syntax for the first time, you are definitely going to have some questions:

如果您是初次使用这种语法,肯定会遇到一些问题:

  • How will I know what data types these fields represent?

    我怎么知道这些字段代表什么数据类型?

  • How am I supposed to know that createView(:) is an operation I can perform on this API?

    我应该如何知道 createView(:) 是我可以在此API上执行的操作?

  • How will I even know that I can ask for these fields?

    我什至怎么知道我可以要求这些领域?

Well, the answer is simply GraphQL Schema Introspection. Clients can introspect the schema provided by the API to generate documentation and validate queries. This is one of my favorite things about GraphQL. You don’t need documentation about the request/response data of every endpoint. Once you introspect the schema, you will be able to see everything that is possible with the API.

好吧,答案很简单,就是GraphQL Schema自省。 客户端可以对API提供的架构进行内部检查,以生成文档并验证查询。 这是我最喜欢的GraphQL之一。 您不需要有关每个端点的请求/响应数据的文档。 内省架构后,您将能够看到API可能实现的所有功能。

In my workflow, I use a tool called Insomnia (https://insomnia.rest/graphql/). It acts as a GraphQL client that can introspect your schema and generate all of necessary documentation. Since Insomnia will now know about your schema, you can test out some queries and mutations on your server with full autocomplete and real time validation support!

在我的工作流程中,我使用了一个名为Insomnia( https://insomnia.rest/graphql/ )的工具。 它充当GraphQL客户端,可以对您的架构进行内部检查并生成所有必要的文档。 由于Insomnia现在将了解您的架构,因此您可以使用完全自动完成和实时验证支持在服务器上测试一些查询和变异!

Finally, now we can get to the bread and butter of this post. It’s cute that you can use insomnia as a client, but we really want our iOS app to be the client!

最后,现在我们可以了解这篇文章的内容。 您可以将失眠症作为客户端很可爱,但我们确实希望我们的iOS应用程序成为客户端!

iOS上的GraphQL问题 (The Problem with GraphQL on iOS)

Image for post

If you stumbled upon this post by looking for resources on how to implement GraphQL on iOS you may have realized that the majority of paths take you to one Framework: Apollo Client for iOS.

如果您通过寻找有关如何在iOS上实现GraphQL的资源而偶然发现了这篇文章,则您可能已经意识到,大部分路径会将您带到一个Framework: Apollo Client for iOS

This is not necessarily a problem, after all Apollo is probably the industry standard implementation for GraphQL on any platform. I’m going to tell you the problems I have with using Apollo Client. These problems may not apply to your use cases, and if they don’t, you should hop over to their docs ASAP to get started!

这毕竟不是问题,毕竟Apollo可能是任何平台上GraphQL的行业标准实现。 我将告诉您使用Apollo Client时遇到的问题。 这些问题可能不适用于您的用例,如果不适用,则应尽快跳至他们的文档以开始使用!

Apollo Client is VERY heavy handed with your app. It will involve itself in your modeling, network, and caching layers. It will introspect your schema and allow you to write your queries with GraphQL query language in text files. It will take the queries you write and generate models and operations in code for you. You will then use Apollo’s networking and caching abstractions to execute those queries in code. Due to all of this work, you can be absolutely sure that your requests will work and the shape of your models are correct (If of course, the schema of the API doesn’t change underneath you).

Apollo Client非常繁重地处理您的应用程序。 它将涉及您的建模,网络和缓存层。 它将内省您的架构,并允许您使用GraphQL查询语言在文本文件中编写查询。 它将接受您编写的查询,并以代码形式生成模型和操作。 然后,您将使用Apollo的网络和缓存抽象在代码中执行那些查询。 由于所有这些工作,您可以完全确定您的请求将起作用并且模型的形状正确(当然,如果您下面的API的架构不变)。

While it’s AWESOME that Apollo Client will do all this for you… it may not be what you want. Maybe your app already has a pretty extensive networking layer with its own caching mechanisms that you’ve come to rely on. Maybe your app hits a plethora of API’s and you’re slowly moving some of them to GraphQL. Maybe you have existing models that for some particular reason, you don’t want to replace with the ones that will be generated by Apollo Client. These are all reasons that have prevented me from integrating this framework into an app. They may be completely invalid reasons for you, especially in the case that you are starting an app from scratch that is going to rely heavily on GraphQL. These are also *my conclusions about this framework, and if there are ways to use it without running into these issues, I would love to hear them or have them clarified in their documentation.

尽管Apollo Client会为您完成所有这些任务真是太好了……但这可能不是您想要的。 也许您的应用程序已经具有相当广泛的网络层,并且拥有自己依赖的缓存机制。 也许您的应用程序使用了过多的API,但您正在将其中一些缓慢地移至GraphQL。 也许您有现有的模型,由于某些特殊原因,您不想将其替换为Apollo Client生成的模型。 这些都是导致我无法将此框架集成到应用程序中的原因。 对于您来说,它们可能完全是无效的原因,尤其是在您要从头启动将严重依赖GraphQL的应用程序的情况下。 这些也是对这个框架的结论,如果有使用它的方法而不会碰到这些问题,我很想听听他们的意见,或者在他们的文档中加以澄清。

Apollo Client iOS的替代品 (Alternatives To Apollo Client iOS)

If we want to avoid the overhead of a heavy handed framework, we are going to have to forgo some of its luxuries. There are a few different ways we can write our requests without Apollo-Client. We will still get the benefits of GraphQL queries (reducing our network calls) but we won’t get to *directly* enjoy schema validation to let us know that what we are doing is possible on our API.

如果我们想避免繁重的框架的开销,我们将不得不放弃它的一些奢侈。 没有Apollo-Client,我们可以通过几种不同的方式编写请求。 我们仍将获得GraphQL查询的好处(减少我们的网络调用),但我们不会直接*享受*模式验证,以使我们知道我们的API上可以做些什么。

At the end of the day the GraphQL request is typically a JSON encoded string in the body of an HTTP POST request. Which means we can generate this string ourselves in code and then shoot it off to our API. This isn’t ideal, it even says so in the GQL docs as an argument for the use of GQL variables:

归根结底,GraphQL请求通常是HTTP POST请求主体中的JSON编码字符串。 这意味着我们可以在代码中自行生成此字符串,然后将其发布给我们的API。 这不是理想的,甚至在GQL文档中这样说,作为使用GQL变量的参数:

“It wouldn’t be a good idea to pass these dynamic arguments directly in the query string, because then our client-side code would need to dynamically manipulate the query string at runtime, and serialize it into a GraphQL-specific format”

“将这些动态参数直接传递到查询字符串中不是一个好主意,因为那样我们的客户端代码将需要在运行时动态处理查询字符串,并将其序列化为GraphQL特定格式”

BUT, it’s really the best we’ve got at the moment without integrating Apollo Client. Luckily there are some open source libraries out there that enable us to build our GraphQL queries in a very Swift friendly way. The one I am currently using is called Sociable Weaver, its a nice lightweight library that lets us use a GraphQL query building DSL powered by the new @functionbuilder Swift language feature. I highly encourage you to check it out!

但是 ,这实际上是我们目前没有集成Apollo Client的最佳选择。 幸运的是,那里有一些开放源代码库,使我们能够以非常友好的Swift方式构建GraphQL查询。 我当前正在使用的一个名为Sociable Weaver ,它是一个不错的轻量级库,可让我们使用GraphQL查询构建由新的@functionbuilder Swift语言功能驱动的DSL。 我强烈建议您检查一下!

Creating a request (called a Weave in this library) looks something like this:

创建一个请求(在该库中称为Weave )看起来像这样:

Weave(.query) {
Object(Post.self) {
Field(Post.CodingKeys.id)
Field(Post.CodingKeys.title)
Field(Post.CodingKeys.content)
}
}

Which will generate the following request

这将生成以下请求

query {
post {
id
title
content
}
}

This is a very basic one, but this library can be used to formulate much more complex requests…

这是一个非常基础的程序,但是该库可用于制定更为复杂的请求…

So what would the workflow look like if you wanted to skirt Apollo-Client iOS and use a library like SociableWeaver?

那么,如果您想跳过Apollo-Client iOS并使用SociableWeaver之类的库,那么工作流程会是什么样?

First, I would recommend getting some sort of GraphQL IDE/Playground/Client whatever you want to call it (As mentioned before I use Insomnia GQL IDE). So you can still introspect your API’s schema and test out requests. This way you know that the requests you plan on building in code will actually be valid. Also, this will give you complete API documentation!

首先,我建议您获得某种GraphQL IDE / Playground / Client,无论您想调用它什么(如在使用Insomnia GQL IDE之前所述)。 因此,您仍然可以内省API的架构并测试请求。 这样,您就知道计划在代码中构建的请求实际上是有效的。 另外,这将为您提供完整的API文档!

Next, use your query building library how you see fit to generate your requests. It’s important to understand how the data comes back from the server so you can decode it properly. In GraphQL you will get back a data field and possibly an operation name that you will have to drill into to get to your response object.

接下来,使用查询构建库以适合您的方式生成请求。 重要的是要了解数据如何从服务器返回,以便可以正确解码。 在GraphQL中,您将返回一个data字段,并可能需要检索一个操作名称,才能到达响应对象。

Keep in mind this approach may seem hacky to some GQL purists, but I find it very useful for mobile developers who don’t want to undergo huge refactors to start supporting some cool new GQL API. I’m sure even more tools will come down the pipeline for more seamless implementations of GraphQL in our iOS apps!

请记住,对于某些GQL纯粹主义者而言,这种方法似乎不明智,但我发现它对于不想进行大量重构以开始支持一些新GQL API的移动开发人员非常有用。 我相信,更多的工具将会在我们的iOS应用程序中实现更无缝的GraphQL实现!

I hope some of this helps and feel free to leave any questions or comments!

我希望其中的一些帮助并随时留下任何问题或评论!

翻译自: https://levelup.gitconnected.com/graphql-for-ios-development-cfeff5bdc043

ios graphql

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值