GraphQL 如何比 REST 更高效?

Posted

技术标签:

【中文标题】GraphQL 如何比 REST 更高效?【英文标题】:How is GraphQL more efficient than REST? 【发布时间】:2020-08-24 23:12:14 【问题描述】:

让我们以 SpaceX 发射 api 为例。 如果我使用 REST(在 Node.js 中)发出请求 它看起来像这样:

router.get('https://api.spacexdata.com/v3/launches', function (req, res) 
    // What to do with it
)

这将为我获取所有启动数据。

现在,使用 GraphQL,您只需指定所需的字段。

const LaunchType = new GraphQLObjectType(
  name: 'Launch',
  fields: () => (
    flight_number:  type: GraphQLInt ,
    mission_name:  type: GraphQLString ,
    launch_year:  type: GraphQLString ,
    launch_date_local:  type: GraphQLString ,
    launch_success:  type: GraphQLBoolean ,
    rocket:  type: RocketType 
  )
)

但是.. 在查询中,您提供与 REST 版本路由相同的路由。

resolve(parent, args) 
      return axios
        .get('https://api.spacexdata.com/v3/launches')
        .then((res) => res.data)
    

那么 GraphQL 请求有何不同?它实际上不是也获取整个数据吗? 它可以在发出请求时以某种方式“遍历”路由吗?

【问题讨论】:

我建议您查看apollographql.com/blog/graphql-vs-rest-5d425123e34b 和howtographql.com/basics/1-graphql-is-the-better-rest 以查看区别,但要回答您的问题,不,除非您要求,否则它不会获取所有内容。如果您只对flight_numbermission_name 感兴趣,它只会返回与您要求的完全相同格式的数据。 REST 将返回所有内容,而您不知道数据的结构。 【参考方案1】:

在您的示例中,服务器实际上确实从底层 REST API 获取整个响应。您的 resolve 函数只是为了获取特定字段的值而调用的函数。无论您在解析器内部还是外部调用 axios.get 都没有关系 - 它仍然会返回相同的内容。

但是,任何向 GraphQL 服务发出请求的客户端都必须指定它想要返回的字段(flight_numbermission_name 等)。当客户端发出请求时,GraphQL 服务会调用 REST API,获取完整响应,然后对其进行转换以反映客户端请求的字段。

这是否比直接调用 REST 端点更有效取决于很多因素。通过仅返回请求的字段,与 REST 端点返回的“完整”响应相比,GraphQL 响应负载可能会更小。但是,GraphQL 确实会增加开销,并且在客户端和 REST API 之间使用任何类型的代理也会增加延迟——这可能会或可能不会被较小有效负载的任何收益所抵消。也就是说,如果您在服务器上缓存来自 REST 端点的响应,则可以加快速度。

【讨论】:

因此,如果我将 GraphQL 发送到 REST 请求,则收益(不考虑其他因素)应该是较少量的响应数据,我将从本地服务器发送回我的客户端。如果我发出 GraphQL 到 GraphQL 请求,我就可以充分发挥请求特定字段的潜力。我猜对了吗?

以上是关于GraphQL 如何比 REST 更高效?的主要内容,如果未能解决你的问题,请参考以下文章

Graphql 是不是比 Rest API 提供任何性能提升?

REST, GraphQL, Webhooks & gRPC 如何选型

精读《REST,GraphQL,Webhooks & gRPC 如何选型》

发现GraphQL端点和SQL注入漏洞

GraphQL 或 REST [关闭]

如何在 GraphQL 中导出字段定义