无论是创建网站还是移动应用,我们都需要通过API来传递数据。通过API,我们可以获取数据库中的数据,操作数据库,处理一些业务逻辑。当今最流行的API架构是REST。然而,GraphQL正在逐渐赶上它。GraphQL是一种新型的API架构,比REST更灵活、更高效,具有声明式数据获取等特性。尽管GraphQL变得非常流行,但它并没有取代REST,因为一些用户发现它更难使用并认为它是一个过度设计的解决方案,尤其是对于一些小项目。REST现代应用程序开发中API的主要架构是REST。大多数后端框架都可以很容易地实现REST。RESTAPI通常通过HTTP方法调用。通过访问一个URL,实现接口的调用处理。REST案例假设您正在创建一个博客站点,在主页上,您将显示最新文章的摘要,包括标题、图片和简短描述。为了提供这些数据,您需要查询后端服务器上的数据库或缓存以获取结果。然后RESTAPI执行GET/api/articles,它将所需数据作为JSON数组返回,如下例所示://GET/articles[{"id":1,"title":"RESTisAwesome","image":"https://restblog.com/img/dsh9a89.png","description":"REST的好处"},{"id":2,"title":"REST是如何工作的","image":"https://restblog.com/img/33szad2.png","description":"了解REST"}]REST的优点易于实施REST易于在Web服务器应用程序中设置,尤其是当我使用一些框架时。比如laravel、express、django、springboot等,它们都提供了非常方便的方法来实现REST接口。例如,/api/articles在带有MongoDB的Express应用程序中设置REST接口非常简单:app.get('/api/articles',async(req,res)=>{try{constarticles=awaitdb.articles.find()res.json(articles)}catch(err){res.status(500).send(err)}})通俗易懂REST通俗易懂,基本就是通过请求方法,请求参数和接口名称,我们只要知道这个接口的作用即可,无论是前端人员还是后台人员都可以通过接口文档方便的进行数据交互。REST的缺点冗余数据回到博客例子,假设我们在创建PC站点的同时创建了一个移动站点。和桌面版一样,在移动端的首页我们也展示了文章摘要。由于手机屏幕较小,这里只需要标题和图片进行总结,描述可以省略。但不幸的是,由于/api/articles接口是固定的,移动端的描述在调用API时仍然会收到这个字段。当这些冗余数据被频繁调用并发送大量数据时,会造成服务器资源的浪费。嵌套数据有时当我们想通过一个接口返回更多的数据时,我们会使用嵌套数据。例如,我们可能需要一篇带有嵌套评论的文章。我们在获取文章的同时,还需要通过文章id获取评论信息。这将导致请求时间的延长。GraphQLREST的数据冗余和低效率促使Facebook工程师在2015年创建了一种新的API设计模式,称为GraphQL。和REST一样,GraphQL不是特定的软件,而是API设计的规范。GraphQL的工作原理要了解GraphQL的优势,我们将快速概述它的工作原理。与REST不同,GraphQL需要一个模式来告诉客户端和服务器允许通过API进行哪些数据和操作。这些是使用GraphQL模式语言定义的,它是一种具有强类型系统的语言不可知格式。GraphQL示例让我们回到获取文章和评论的示例。在我们的GraphQL模式中,我们将定义一个Article类型,其中包含一个必需的整数id字段和一个可选的title和image字符串字段描述,如下所示:typeArticle{id:Integer!title:Stringimage:Stringdescription:String}除了基本的标量类型,schemaobjects还可以相互引用。我们可以创建类型和评论之间的一对多关系,如下所示:typeArticle{id:Integer!title:Stringimage:Stringdescription:Stringcomments:[Comment]}typeComment{content:Stringarticle:Articleauthor:Author}定义操作GraphQL模式的另一个重要用途是定义操作,包括读取数据和写入数据的查询。这里我们提供一个查询文章:typeArticle{id:Integer!title:Stringimage:Stringdescription:Stringcomments:[Comment]}typeComment{content:Stringarticle:Articleauthor:Author}typeQuery{articles:[Article]}GraphQL声明式数据获取的好处GraphQL的杀手级特性是声明式的数据获取,客户端可以在其中准确指定所需的数据。这可以包括特定字段,甚至在嵌套对象中。我们之前看到必须在模式上定义操作。但是,在这些操作中,我们可以指定希望查询返回的字段受模式限制。例如,我们可以创建一个查询,其中Articles只获取我们想要的字段,无论Comments是否嵌套。请参见下面的示例:query{articles{idtitleimagedescriptioncomments{content}}}这是将从该查询返回的数据结构。请注意,在GraphQL响应中收到的数据将与请求它的查询具有相同的结构。{"data":{"articles":[{"id":1,"title":"REST很棒","image":"https://restblog.com/img/dsh9a8.png","description":"一篇关于REST的文章","comments":[{"content":"GraphQL更好!"}]}}这样,GraphQL消除了冗余数据和嵌套数据问题。由于强类型和预定义的查询要求,GraphQL可以提供开箱即用的验证和类型检查。反过来,这意味着GraphQL本质上是自文档化的。只要字段、类型或查询发生变化,基于模式的文档就可以自动更新。没有版本控制的API每次应用更改时,API可能也需要更改。例如,假设我们决定重命名实体中的描述字段。REST通过提供多个版本来处理这个问题,这对API开发人员来说很麻烦。使用GraphQL,可以在不影响现有查询的情况下从架构中删除不推荐使用的字段。这为应用程序提供了对新功能的持续访问,并鼓励更清洁、更易于维护的代码。GraphQL的缺点是矫枉过正一些开发人员认为,GraphQL解决的问题往往被夸大了。例如,对于大多数小型应用程序,由于几个字节的冗余数据,设计更复杂可能不符合成本效益。难以学习GraphQL比REST更难实现,这为新用户提供了更难的学习曲线。难以缓存GraphQL经常被批评为更难缓存。REST客户端受益于HTTP缓存,因为所有端点都是URL,而GraphQL客户端需要实现自己的自定义解决方案。总结虽然REST架构在过去十年中主导了Web开发,但它对接口调用的使用使其在某些情况下有些不灵活且效率低下。GraphQL通过提供一种严格类型化的模式语言来解决这些问题,接口的调用者可以根据自己的需要进行查询。如果未来有更好的设计结合两者的优点,相信会是最好的方案。
