2015年,Facebook开源了GraphQL。从那以后,它在前端网络中得到了普及。传统的RESTAPI有什么问题?GraphQL有什么优势?在本文中,我们将深入探讨GraphQL的设计原则,比较GraphQL与REST的异同,并讨论GraphQL相对于其他架构的优势。1您的API应该使用哪种技术?自Facebook在2015年开源GraphQL规范以来,它在前端Web开发中迅速流行起来。为什么这项新技术会突然流行起来?与传统的RESTAPI相比,GraphQL有哪些优势?我们将讨论GraphQL的设计原则,将GraphQL与REST中的相同请求进行比较,并深入探讨GraphQL相对于其他架构的优势。要了解GraphQL作为API架构的好处,让我们讨论API在客户端-服务器架构中的作用。API(应用程序编程接口)是一个中间层,它允许服务器从客户端接收对结构化数据的请求,并为请求的数据发送结构化响应。设计API架构的方法有很多种。让我们来看看使GraphQL适合现代Web应用程序的重要基本设计原则。2GraphQLServer的设计原则GraphQL规范概述了5条设计原则,使其成为现代前端开发的良好解决方案。让我们看看GraphQL的设计原则,并使用FacebookNewsFeed作为我们的用例。查询是分层结构的,使用分层和嵌套的字段格式将查询与响应数据一对一匹配。查询和响应是树状的,可以查询每个项目的附加嵌套字段。在Facebook的新闻源中,此结构允许单个查询返回帖子列表、每个特定帖子的评论以及每个评论的点赞数。该结构以产品为中心,关注前端如何接收数据,并构建交付数据所需的运行时。这使得Facebook的newsfeed可以通过一个请求从后端获取所有它需要的数据,使服务器能够根据GraphQL规范从不同的端点获取数据。它使用特定于应用程序的类型系统,使开发人员能够确保查询使用有效类型并且在执行之前在语法上是正确的。例如,新闻源的GraphQL模式要求字段“user”必须包含一个字符串,而“likes”必须包含一个数字。如果查询尝试添加不同类型的输入,GraphQL将在执行查询之前抛出错误。GraphQL查询是在客户端指定的,因此客户端确切地知道它将以何种格式接收数据。这意味着如果前端请求的格式是发布包含用户名、评论和点赞的数据,则来自Facebook的请求newsfeed将构建在单个对象中,而不是像其他体系结构那样构建在多个单独的数据块中。使用GraphQL的服务器结构必须是自省的,或者可以由GraphQL本身查询。因此出现了像GraphiQL或GraphQL游乐场这样的强大工具。这两种工具都允许Facebook开发人员准确查看他们的服务器上正在使用哪些查询和字段。讨论向GraphQL的转变以及这些设计原则如何有益于开发。我们首先深入研究传统的RESTAPI架构及其不足之处。3传统RESTful架构REST架构的设计范式侧重于分配HTTP请求方法(GET、POST、PUT、PATCH、DELETE)和URL端点之间的关系。在REST架构中,方法和端点的每种组合都会产生不同的封装功能。如果客户端需要特定端点/方法未提供的数据,则可能需要其他请求。从REST请求返回的数据格式取决于端点——无法保证此数据将按照前端需要的方式进行格式化。为了使用响应中的数据(与端点默认返回的格式不同),数据解析和数据操作必须在客户端编写。接下来,让我们看看GraphQL规范与REST有何不同,以及它的优势。这些优点使这种新架构成为解决客户端和服务器之间数据传递问题的特别合适的解决方案。4GraphQL架构与RESTfulAPI一样,GraphQLAPI旨在处理HTTP请求并提供对这些请求的响应。无论如何,这就是相似之处。RESTAPI建立在请求方法和端点之间的连接之上,而GraphQLAPI旨在仅通过一个端点,始终使用POST请求进行查询,通常是yourdomain.com/graphqlURL。请求到达GraphQL端点后,客户端请求的有效负载完全在请求正文中处理。这个请求体必须遵循GraphQL规范,API必须有适当的服务器端逻辑来处理这些请求并提供适当的响应。这提供了比RESTfulAPI更流畅的客户端体验,RESTfulAPI可能需要客户端对多个数据块发出多个请求,并在数据返回后对其进行操作。为了说明GraphQL如何实现这一点,让我们分解一下GraphQL服务器的结构。5GraphQLServer启用GraphQL逻辑的服务器端逻辑由定义服务器功能的Documents组成。这些文档包含可执行文件和类型系统定义。顾名思义,类型系统定义定义了每个数据字段的输入和结果可接受的类型和格式。可执行文件包含要处理的可能操作列表,包括操作类型(查询、修改或订阅)、操作名称、要查询或写入的字段,以及准确定义返回内容的选择集从运营数据来看。选择是GraphQL的最大价值所在——它们允许客户端查询特定数据集并接收包含请求信息的响应:不多也不少。GET/graphql?query={books(id:12){authors{firstName,lastName}title,yearPublished,length}{Query{//operationtypebooks(id:12){//operationendpointauthors{//requestedfieldsfirstNamelastName}titleyearPublished}}}有关GraphQL规范的结构和语法的更多信息,请参阅GraphQL的文档。(https://graphql.github.io/graphql-spec/June2018/#sec-Overview)接下来,我们将看看GraphQL中的查询结构。6GraphQL查询解析下面是一个结构化的GraphQL查询,获取特定书籍的数据,包括作者的名字和姓氏GET/graphql?query={books(id:12){authors{firstName,lastName}title,yearPublished,length}{Query{//operationtypebooks(id:12){//operationendpointauthors{//requestedfieldsfirstNamelastName}titleyearPublished}}}这都可以通过一个查询由GraphQL服务器逻辑解析和处理。当与REST架构中相同结构的请求进行比较时,GraphQL的优势开始显现。让我们看看下面的REST请求结构,然后突出显示一些差异!7REST请求解析要向RESTAPI发出同样的请求,客户端首先需要向一个可以返回图书数据的端点发送请求,并传入图书id作为参数:GET/books/12这个请求可能会返回包含特定书籍的请求所有数据的对象,例如:{"title":"TheHitchhiker'sGuidetotheGalaxy","authorID":42,"yearPublished":1978,"length":208,"genre":"ScienceFiction"}在我们的示例中,与相同的GraphQL查询相比,此响应有两个缺点:REST响应包含额外的数据,如流派,返回的信息比我们需要的多。REST需要再发出一个请求以获取我们实际要查找的数据:该特定作者的所有书籍。要获取此数据,我们需要使用authorID发出额外请求:GET/authors/42此请求的响应应包含我们要查找的所有数据:{"firstName":"Douglas","lastName":"Adams"}既然我们已经有了我们需要的所有图书和作者数据,响应解析就由客户端完成了。如今,前端应用程序必须结合来自不同端点的数据以获得所需的功能。总的来说,与RESTAPI相比,GraphQL提供的性能优势可以为前端开发人员带来回报。使用GraphQL规范创建服务器可能需要更多设置以及编写预测性服务器端逻辑来解析和处理请求。虽然GraphQL的设置成本可能比传统的REST架构高,但更易于维护的代码、强大的开发工具和简化的客户端查询的好处通常超过成本。
