给它一个REST:对您的API使用GraphQL

by David Celis

大卫·塞利斯(David Celis)

给它一个REST:对您的API使用GraphQL (Give it a REST: use GraphQL for your APIs)

In the world of API architecture, REST has been the reigning ruler for a decade or more. Chances are that you use software built on a REST API multiple times per day on your phone, computer, or some other device. Maybe you’ve even worked on a REST API or written one yourself! Despite REST’s popularity, however, it has a few glaring flaws.

在API体系结构的世界中,REST已成为统治者10多年。 可能您每天在手机,计算机或某些其他设备上多次使用基于REST API构建的软件。 也许您甚至使用过REST API或自己编写了一个! 尽管REST非常流行,但是它仍然存在一些明显的缺陷。

什么是REST? (What is REST?)

In REST APIs, the server defines a specific set of resources that a client can request, and these resources are defined by unique URLs. For example, in the API for a generic microblogging platform, the URL /users/1 may denote the first user in the system, /users/1/posts could return a collection of all posts that user has written, and /users/1/posts/327 could return a single post. REST has many nuances and a well-documented specification for behavior, but URL-based resources cover the basic idea. What is ultimately important is that the server defines the structure of the data that the client can request.

在REST API中,服务器定义了客户端可以请求的一组特定资源,并且这些资源由唯一的URL定义。 例如,在通用微博平台的API中,URL /users/1 可以表示系统中的第一个用户, /users/1/posts可以返回该用户已写的所有帖子的集合, /users/1/posts/327可以返回一个帖子。 REST有很多细微差别,并且有详细的行为规范,但是基于URL的资源涵盖了基本概念。 最终重要的是服务器定义客户端可以请求的数据结构。

REST怎么了? (What’s wrong with REST?)

Imagine you work for the aforementioned Generic Microblogginator™ company as a mobile app developer. You’re given the task of writing the mobile view for a user’s profile, which needs to show information about the user and list their posts. This isn’t too difficult; just hit the /users/{id} endpoint to get the former, and /users/{id}/posts to get the latter.

想象一下,您是作为移动应用程序开发人员为上述Generic Microblogginator™公司工作的。 您的任务是为用户的个人资料编写移动视图,该视图需要显示有关用户的信息并列出他们的帖子。 这不太困难; 只需点击/users/{id}端点即可获得前者,而/users/{id}/posts可获得后者。

You ship the mobile view and wait to be ✨dazzled✨ by all of the customer feedback and app reviews. Next week, once all of the reviews have poured in, you get a new requirement. That Other Microblogger™ shows a couple of comments on each post in their profile view. Why don’t we do that, too? Luckily, your API already has an endpoint to get a blog post’s comments: /users/{id}/posts/{id}/comments. You change the view to hit that endpoint for each post you show on a user’s profile page, and you’re done.

您发布了移动视图,并等待所有客户反馈和应用评论让您眼花azz乱。 下周,所有评论都涌入后,您将获得新的要求。 Other Microblogger™在其个人资料视图中的每个帖子上显示了一些评论。 我们为什么也不这样做呢? 幸运的是,您的API已经具有一个端点来获取博客文章的评论: /users/{id}/posts/{id}/comments 。 您可以更改视图以击中用户个人资料页面上显示的每个帖子的端点,然后完成操作。

But now your app is slow, and this leads us to one of the major problems with REST APIs:

但是现在您的应用程序运行缓慢,这使我们面临REST API的主要问题之一:

HTTP请求过多 (Too many HTTP requests)

Let’s face it: client applications rarely stay simple. More often than not, each client has a fairly specific set of requirements that reflect what data they need from your system. If you provide only one absolute way to request data, you’ll get clients trying to ram a rhomboid peg into a diamond-shaped hole.

让我们面对现实:客户端应用程序很少保持简单。 通常,每个客户端都有一组相当具体的要求,以反映他们从系统中需要什么数据。 如果您仅提供一种绝对的方式来请求数据,则会使客户尝试将菱形钉撞入菱形Kong中。

In our previous example, our mobile app will become slower and slower with each post a user writes. If a user has twenty posts listed on their profile, we’re issuing 22 API requests. One for information on the user, one for their list of posts, and then twenty requests to get each post’s comments.

在前面的示例中,我们的移动应用随着用户撰写的每条帖子而变得越来越慢。 如果用户的个人资料上列出了20条信息,我们将发出22条API请求 。 一个用于向用户提供信息,一个用于其帖子列表,然后二十个请求以获取每个帖子的评论。

As you add more components to your mobile app’s interface, this problem will get worse. With each new UI component comes a new API call or a new customization to existing API endpoints. You can nest objects within each other to avoid extra API calls, but as your view becomes more complex, you’ll inevitably start nesting irrelevant data. You’ll end up with endpoints that don’t describe a single resource but, instead, a view of multiple resources. Now your API doesn’t seem so RESTful anymore.

随着在移动应用程序界面中添加更多组件,此问题将变得更加严重。 每个新的UI组件都会附带一个新的API调用或对现有API端点的新自定义。 您可以相互嵌套对象以避免额外的API调用,但是随着视图变得越来越复杂,您将不可避免地开始嵌套无关的数据。 您将得到的终结点不是描述单个资源,而是描述了多个资源。 现在,您的API似乎不再那么RESTful。

Even worse, you’ll need to support any old endpoints as long as there are old versions of clients in the wild lest you risk breaking those clients. This leads to another major problem with REST:

更糟糕的是,只要有旧版本的客户端,就需要支持所有旧的端点,以免冒着破坏这些客户端的风险。 这导致了REST的另一个主要问题:

“版本化” REST API很痛苦 (“Versioning” REST APIs is a pain)

The structure of responses from REST APIs is important. Clients build themselves around the knowledge that each resource has a specific structure. When Generic Microblogginator™ first released their API, this is what the response for getting a single post looked like:

REST API响应的结构很重要。 客户基于对每种资源都有特定结构的认识来建立自己。 当Generic Microblogginator™首次发布其API时,获得单篇帖子的响应如下所示:

After some time has passed, you decide there are a couple things you want to improve about a post’s structure in the API. Posts are about to get categories, so you’ll need to add those as a new field. You’ve also received feedback that the format for published_at isn’t very friendly. JavaScript clients can parse it okay, but you’d rather any tool be able to parse your timestamps easily, so you decide to change it to an ISO-8601 format. When all is said and done, you want the new structure to look like this:

经过一段时间后,您决定要对API中的帖子结构进行一些改进。 帖子即将获得类别,因此您需要将其添加为新字段。 您还收到了有关published_at的格式不太友好的反馈。 JavaScript客户端可以解析它,但是您希望任何工具都能够轻松解析您的时间戳,因此您决定将其更改为ISO-8601格式。 说完所有内容后,您希望新结构看起来像这样:

Looking good! Unfortunately, one of your changes will break all of your existing clients. Every client expects published_at to be the less-friendly format, so that’s how they’ll try to parse it. If you want to update a field or remove a field, you have to version your API (whether it’s via the URL or an HTTP header) and try to get clients to upgrade. It’s unlikely you’d get every client to upgrade, so you have two choices:

看起来不错! 不幸的是,您所做的一项更改将破坏您现有的所有客户。 每个客户都希望published_at是不太友好的格式,因此这就是他们尝试解析的方式。 如果要更新字段或删除字段,则必须对API进行版本控制(无论是通过URL还是通过HTTP标头),并尝试使客户端升级。 您不太可能让每个客户端升级,因此有两种选择:

  1. Be okay with breaking old versions of clients (including your own app)

    可以破坏旧版本的客户端(包括您自己的应用程序)
  2. Support old versions of your API until the day your company decides to announce a new chapter in their incredible journey.

    支持旧版本的API,直到您的公司决定宣布其令人难以置信的旅程的新篇章为止。

The easiest thing to do is simply leave your old code alone, which means piling more and more versions of your API versions on top of the old ones.

最简单的方法就是简单地保留旧代码,这意味着在旧代码之上堆积越来越多的API版本。

挑战者进场 (A challenger approaches)

Enter GraphQL, a technology written by Facebook. Facebook was facing major problems with the data pipeline for their mobile applications. Their mobile apps used to be wrappers around web views and, as the mobile apps increased in complexity, they began to suffer performance problems and frequent crashes. Facebook turned to writing native applications and found themselves needing a new API to retrieve data for their native views. They evaluated REST and other options but, given problems like those described above, ultimately took the opportunity to produce something truly new.

输入GraphQL,这是Facebook编写的技术。 Facebook在其移动应用程序的数据管道方面面临重大问题。 他们的移动应用曾经是围绕Web视图的包装,并且随着移动应用复杂性的提高,他们开始遭受性能问题和频繁崩溃的困扰。 Facebook转向编写本机应用程序,发现自己需要一个新的API来检索其本机视图的数据。 他们评估了REST和其他选项,但是,鉴于上述问题,最终利用这次机会生产了一些真正新颖的产品。

什么是GraphQL? (What is GraphQL?)

GraphQL is, as the name might suggest, a query language. It’s also perfect for APIs. It allows you to define your data using a fully-fledged type system, forming a schema that is self-documenting. It also gives clients full control over the data they request.

顾名思义,GraphQL是一种查询语言。 它也是API的完美选择。 它使您可以使用成熟的类型系统定义数据,形成自我记录的模式。 它还使客户可以完全控制他们请求的数据。

HTTP请求太多? 一个HTTP请求怎么样? (Too many HTTP requests? How about one HTTP request?)

With GraphQL, clients can get all of the data they need to render a view using only one request. With our previous profile page example, a client would need to issue one request to get a user’s information, one request to get that user’s posts, and then another request for each post to get a few comments. With GraphQL, that client could get all of the above data with one request:

借助GraphQL,客户端仅需一个请求即可获得渲染视图所需的所有数据。 在我们之前的个人资料页面示例中,客户需要发出一个请求以获取用户的信息,一个请求以获取该用户的帖子,然后发出另一个请求以获取每个评论以获取一些评论。 使用GraphQL,该客户端可以通过一个请求获得上述所有数据:

Boom! ? There are other benefits to this aside from the fact that we went from 22 HTTP requests to one. For instance, your User may have other information attached to it. Maybe you expose the timestamp of when a user signed up. Maybe another client doesn’t care about a post’s categories. If a client doesn’t need to query for a piece of data, neither does your server. So when a client saves, you can save too by simplifying your own database queries.

繁荣! ? 除了我们从22个HTTP请求变为一个HTTP请求之外,这还有其他好处。 例如,您的用户可能附加了其他信息。 也许您公开了用户注册的时间戳。 也许另一个客户不在乎帖子的类别。 如果客户端不需要查询数据, 则服务器也不需要 因此,当客户端保存时,您也可以通过简化自己的数据库查询来保存。

版本控制? 只是弃用! (Versioning? Just deprecate!)

As with (most) REST APIs, you can add fields to GraphQL types without fear. To remove functionality, GraphQL includes deprecation as a feature. Instead of fully removing a field and breaking clients, you can declare a field as deprecated and hide it from tools as it ages.

与(大多数)REST API一样,您可以不用担心将字段添加到GraphQL类型。 为了删除功能,GraphQL包含了弃用功能。 您可以声明一个字段已弃用,而不是完全删除一个字段并破坏客户,然后随着时间的推移将其隐藏在工具中。

文档:您几乎不必担心它 (Documentation: you’ll barely need to worry about it)

Let me be real for a second here: I can count the number of times I’ve used a well-documented API on one hand. Many times, APIs remain undocumented or poorly documented. With GraphQL, your schema is practically self-documenting. All you have to do is give your types and fields descriptions when necessary, and this happens in the code itself. Clients can issue special GraphQL queries to introspect on your application’s schema and know, in one query, all of the data they can request, what it’s called, and what it describes. Developers can also use tools that are built on this introspection like GraphiQL, which allows clients to test their queries with live syntax highlighting and error detection.

在这里让我成为现实:一方面我可以算出我使用了一个有据可查的API的次数。 很多时候,API仍未记录或记录不良。 使用GraphQL,您的架构实际上是自记录的。 您所要做的就是在必要时提供您的类型和字段描述,而这种情况发生在代码本身中。 客户端可以发出特殊的GraphQL查询来对应用程序的模式进行内部检查,并在一个查询中知道他们可以请求的所有数据,调用的数据以及描述的内容。 开发人员还可以使用基于此自省构建的工具,例如GraphiQL ,该工具允许客户端使用实时语法突出显示和错误检测来测试其查询。

GraphQL入门 (Get started with GraphQL)

Are you sold enough to try out GraphQL? There are plenty of resources to help you get started on your journey:

您的销售量足以试用GraphQL吗? 有很多资源可以帮助您开始旅程:

I’ll also be following this post up with one more, in which we’ll create a little GraphQL API together, so stay tuned! I’ve had the immense pleasure of working with GraphQL at GitHub and my experience leads me to believe wholeheartedly that it’s the API tool of the future.

我还将在这篇文章之后再发表一篇,其中我们将一起创建一个GraphQL API,敬请期待! 我在GitHub上使用GraphQL感到非常荣幸,我的经验使我全心全意地相信这是未来的API工具。

翻译自: https://www.freecodecamp.org/news/give-it-a-rest-use-graphql-for-your-apis-40a2761e6336/

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值