简介 随着Web和移动应用程序变得越来越成熟和复杂,软件工程师发明了巧妙的新方法来改善应用程序中客户端和服务器之间的交互。在过去的几年里,在这方面最大的范式转变之一是GraphQL,一种用于操作API的开源查询语言和运行时。GraphQL由Facebook于2012年设计(并于2015年公开发布),旨在通过制作一个声明式、客户端驱动和高性能的新系统来解决传统REST架构的各种弱点。 在本文中,您将了解GraphQL是什么,熟悉GraphQL的重要术语和概念,并发现GraphQL规范与REST架构风格相比如何。GraphQL是什么? GraphQL代表图形查询语言,但与其他查询语言(如SQL(结构化查询语言))不同,它不是一种直接与数据库通信的语言,而是一种定义客户端与API服务器通信的契约的语言。GraphQL规范是一个描述语言规则和特征的开放标准。它还提供了执行GraphQL查询的说明。 由于GraphQL是由开放标准定义的,因此没有正式的GraphQL实现。GraphQL实现可以使用任何编程语言编写,与任何类型的数据库集成,并支持任何客户端(例如移动或Web应用程序),只要它遵循规范中概述的规则即可。最流行的商业GraphQL实现之一是ApolloGraphQL,它吹捧了几个GraphQL客户端和服务器实现,但没有必要使用Apollo来使用或理解GraphQL。GraphQL特性 GraphQL设计有几个关键特征。GraphQL查询是声明性和分层的,而GraphQL模式是强类型和内省的。Declarative声明 GraphQL查询是声明性的,这意味着客户端将准确声明它感兴趣的字段,并且响应将仅包含这些属性。 此示例针对假设的幻想游戏API的GraphQL查询请求ID为1的向导,并请求该对象的名称和种族字段。{wizard(id:1){namerace}} 以JSON格式返回的响应将返回一个数据对象,其中包含找到的向导对象,其中包含查询请求的两个字段。{data:{wizard:{name:Merlin,race:HUMAN}}} 由于GraphQL响应只为您提供所需的确切信息,因此与始终提供完整数据集的替代方案相比,它会产生更高效、性能更高的网络请求。Hierarchical层次 GraphQL查询也是分层的。返回的数据遵循查询的形状。在此示例中,查询已扩展为包括法术,并请求每个法术的名称和攻击字段。{wizard(id:1){namespells{nameattack}}} 响应现在将包括与此特定向导关联的所有拼写对象的数组。尽管向导和咒语可能存储在单独的数据库表中,但它们可以通过单个GraphQL请求获取。(但是,GraphQL对数据本身的存储方式并不固执己见,所以这是一个假设。{data:{wizard:{name:Merlin,spells:〔{name:LightningBolt,attack:2},{name:IceStorm,attack:2},{name:Fireball,attack:3}〕}}}Stronglytyped强类型 GraphQL是强类型,如GraphQLType系统所述。类型描述了GraphQL服务器中值的功能。大多数程序员都熟悉GraphQL类型,具有字符串、布尔值和数字整数等标量(基元值),以及对象等更高级的值。 本示例创建一个拼写对象类型,其中包含与字符串和Int标量类型对应的字段。typeSpell{name:String!attack:Intrange:Int} GraphQL模式是使用类型系统定义的,它允许服务器在尝试查询数据之前确定查询是否有效。GraphQL验证确保请求在语法上正确、明确且无错误。Selfdocumenting自我记录样式 内省功能允许GraphQL客户端和工具查询GraphQL服务器以获取底层模式的形状和数据。这允许创建诸如GraphiQL、用于处理GraphQL查询的浏览器内IDE和游乐场等工具,以及其他用于自动生成文档的工具。 例如,您可以通过schema通过此自省功能了解有关咒语类型的更多信息。{schema{types{namekinddescription}}} 响应也将像任何其他GraphQL响应一样是JSON。{data:{schema:{types:〔{name:Spell,kind:OBJECT,description:Apowerfulspellthatawizardcanreadfromascroll。}〕}}}Clientdriven客户端驱动 开发GraphQLAPI的工作发生在后端,其中模式是定义和实现的。但是,由于GraphQLAPI的所有功能都包含在服务器上的单个端点中,因此由客户端通过声明性查询来决定它到底需要哪些数据。这使开发人员能够快速迭代,因为前端开发人员可以继续查询GraphQLAPI公开的数据,而无需执行任何其他后端工作。Architecture架构 GraphQL存在于客户端和数据之间的应用层中。GraphQL服务器描述API中公开的功能,客户端描述请求的要求。Server服务端 GraphQLAPI由单个端点定义,通常是graphql端点,可以访问GraphQL服务器的全部功能。由于GraphQL是一种应用层技术并且与传输无关,因此它可以通过任何协议提供服务,但最常见的是通过HTTP提供。 GraphQL服务器实现可以使用任何编程语言编写,例如expressgraphql中间件,它允许您在NodeExpressHTTP服务器上创建GraphQLAPI。GraphQL也是与数据库无关的,应用程序的数据可以存储在MySQL、PostgreSQL、MongoDB或任何其他数据库中。数据甚至可以由多个传统RESTAPI端点的聚合提供。重要的是数据是在GraphQL模式中定义的,该模式通过描述可供查询的数据来定义API。Client客户端 向GraphQL服务器发出的请求称为文档,由查询(用于读取请求)和突变(用于写入请求)等操作组成。 虽然有高级的GraphQL客户端,如ApolloClient或Facebook的Relay,它们提供了缓存机制以及额外的工具,但不需要特殊的客户端来向GraphQL服务器发出请求。一个简单的XMLHttpRequest或从Web浏览器获取就足以通过将GraphQL文档发送到GraphQL服务器来发出请求。 下面是一个到graphql端点的获取请求示例,该端点将GraphQL文档作为字符串传递到POST请求的正文中。asyncfunctionfetchWizards(){constresponseawaitfetch(graphql,{method:POST,headers:{ContentType:applicationjson,},body:JSON。stringify({query:{wizards{idname},},}),})constwizardsawaitresponse。json()returnwizards}fetchWizards() 这将返回请求的JSON响应。{data:{wizards:〔{id:1,name:Merlin},{id:2,name:Gandalf}〕}}GraphQLvs。REST GraphQL和REST不是可互换的概念,但它们解决了类似的应用程序问题。REST代表具象状态传输,是一种用于在不同系统之间共享数据的软件架构风格。RESTfulAPI是遵循REST原则和约束的API,包括无状态、可缓存、在客户端和服务器之间强制分离关注点,以及具有统一的接口(例如通过URI)。如前所述,GraphQL是用于执行查询的查询语言和运行时的规范。 这两个系统都有优点和缺点,并且在现代API开发中都有其用途。然而,GraphQL的开发是为了对抗REST系统的一些弱点,并创建一个更高效的、客户端驱动的API。Architecture架构RESTAPI通常由服务器上的多个端点定义,但GraphQL通过单个端点交换数据。GraphQL端点可以返回可能需要多个REST查询的复杂数据图,从而减少单个视图通过网络的请求数量。Datafetching获取数据RESTAPI返回在服务器上确定的数据集。这可能是太多的数据,例如,如果视图只需要响应中的一个属性,或者可能还不够,例如列表终结点不返回表中表所需的每个属性。GraphQL防止这种情况通过声明性查询过度和不足地获取数据。ErrorHandling错误处理由于GraphQL没有必要通过HTTP提供,因此没有关于使用HTTP响应代码处理错误的规范。通常,所有GraphQL端点都将使用200HTTP代码响应进行解析,失败的结果将在响应中的数据属性旁边包含一个错误属性。另一方面,RESTfulAPI使用不同的400级HTTP代码来处理客户端错误,并使用200级HTTP代码来成功响应。Versioning版本管理GraphQLAPI努力向后兼容并避免中断性更改,这与版本控制端点的常见REST模式形成鲜明对比,通常在URL本身中使用v1或v2来确定版本。但是,可以使用GraphQL实现自己的版本控制,或者使用REST通过演进实现版本,只是不那么传统。Caching缓存可缓存性是REST指导约束的一个组成部分。由于基于HTTP的RESTAPI由使用不同HTTP方法的多个终结点组成,因此它可以利用现有的HTTP约定进行缓存并避免重新获取资源。由于基本上每个GraphQL请求都是不同的,但使用单个端点,因此它无法利用任何内置的HTTP缓存机制。GraphQL客户端可以利用全局对象识别来启用简单缓存。 这个列表并没有涵盖REST和GraphQL之间的所有异同,但总结了许多最关键的点。此外,GraphQL可以用作聚合多个REST端点或服务的网关,在这种情况下,这两种技术可以并排使用。 特征 GraphQL REST 描述 GraphQL是一种用于API的查询语言,也是服务器端运行时 用于设计Web服务的体系结构样式 DataFetching获取数据 响应确定性查询的单个HTTP终结点 一组通常返回预定数据集的HTTP终结点Versioning 版本管理 不鼓励版本控制 常见版本控制 HTTP状态码 所有响应(包括错误)通常为200 实现HTTP状态代码 Validation 内置元数据验证 必须手动实施验证 Documentation 内置过孔类型系统和自省 不是自我记录的,像OpenAPI这样的工具可用Caching 缓存 无 有 请求方法 查询、更改和订阅(通过HTTP的POST) 使用的所有HTTP方法(GET,POST,PATCH,PUT,DELETE等) 响应内容类型 JSON Any(JSON,XML,HTML,etc。)总结 GraphQL是一种开源查询语言和API运行时。GraphQL由Facebook的开发人员发明,旨在通过为API制作客户端驱动的声明性查询语言来解决传统RESTAPI遇到的各种问题,例如获取数据过多不足和网络请求效率低下。 虽然GraphQL不是与REST互换的概念,但它们都描述了管理客户端和服务器之间通信的不同方法。在本文中,您了解了GraphQL是什么,GraphQL和REST之间的主要区别和相似之处,以及GraphQL服务器如何向客户端公开数据。