• 请不要在回答技术问题时复制粘贴 AI 生成的内容
Ayanokouji
V2EX  ›  程序员

GraphQL 有什么优缺点

  •  
  •   Ayanokouji · Mar 12, 2022 · 9763 views
    This topic created in 1696 days ago, the information mentioned may be changed or developed.

    如果后端主导使用 GraphQL ,请问使用,还需要避免踩那些坑

    Supplement 1  ·  Mar 18, 2022
    各位不好意思,前几天被限制 720 天不能发言
    现在想问下 2022 年 graphql 的生态怎么样了,比如 java 有 dgs ,写起来也挺方便的
    30 replies  •  2023-08-01 18:21:32 +08:00
    pupboss
    pupboss
    Mar 12, 2022❤️3
    1
    好处主要是可以省流量,省 http 请求次数,坏处其实挺多的,比如鉴权,限流,缓存,性能浪费

    如果你感兴趣的话可以看看这篇:GraphQL 后端架构的经验分享 https://www.pupboss.com/post/2021/experience-sharing-of-graphql-backend/
    bojue
    bojue
    Mar 12, 2022
    2
    @pupboss 现在采用的多不多,我们项目目前遇到的问题是都后端传递字段太臃肿了,每次后端修改字段要等待资源挺麻烦的
    codehz
    codehz
    Mar 12, 2022 via Android
    4
    缺点:自带自省功能(对于一些实现来说不是那么容易关闭),攻击者可以轻易获取所有 api (
    hooopo
    hooopo
    Mar 12, 2022
    5
    太难了
    pupboss
    pupboss
    Mar 12, 2022
    6
    @bojue 看你的描述好像是说向前兼容的问题,GraphQL 它本质上就是个 API 聚合器,后端该遇到的问题它一个也不会少(我好像还没遇到什么场景下 GraphQL 有碾压型的优势
    auh
    auh
    Mar 12, 2022
    7
    前端如果没有复杂业务。后端用这个,就是浪费。
    micean
    micean
    Mar 12, 2022
    8
    当需要一些关联的数据的时候,比较方便,相当于本来需要人工聚合的部分,框架帮你做了。
    缺点主要是鉴权麻烦,至于安全问题,觉得暂不用考虑。
    XCFOX
    XCFOX
    Mar 12, 2022❤️6
    9
    正好最近在做的项目前后端深度使用 GraphQL 。

    优点:
    1. 强类型文档。GraphQL 本身首先是一门语言,而且是强类型语言,目前社区已有各种语言与 GraphQL 转换的工具。实践中,前端配合自动生成工具和 TypeScript 能确切知道每个 Query 每个变量每个属性的类型,省去了以往 RESTful API 项目中前端手动声明类型的麻烦。使用如果后端使用 TypeGraphQL 或者 NestJS 这类框架,能直接从 TypeSCript 的 Class 生成文档(schema)。

    2. 自动聚合。以往 RESTful API 的每个接口的数据都是预先设计好的,前端展示的数据和后端返回的数据有时匹配不上,复杂的业务往往需要一层 BFF 层来做数据聚合。GraphQL 的返回数据是由前端决定的,能有效降低前后端的数据耦合程度,并且减少接口调用次数。

    3. 更细致的鉴权。RESTful API 的鉴权颗粒度只停留在路由上,但是 GraphQL 能控制每个字段的访问权限。(讲道理 RESTful 也能,无非实现起来麻烦点)

    缺点:
    1. 迁移成本高。
    2. 生态不完善。如果后端要用 GraphQL 的话目前几乎只能选 Node.js 了。其他语言生态都不完善,缺少 dataloader 、federation 等关键包库。
    其他方面我觉得和 RESTful 相比,GraphQL 简直完胜啊

    坑:
    1. 著名的 N+1 问题。对于后端来说,需要对每一个列表查询进行优化避免 N + 1 。目前流行的解决方案是 dataloader 。
    2. 每个前端项目只能有一张 GraphQL schema 。这使得后端必须部署一个网关来整个各个微服务,目前几乎只能用 Apollo Federation 来解决这个问题。
    3. Subscriptions 。Apollo 实现了 Subscriptions 功能来帮助服务器主动发送消息。但是实践下来发现这个功能还是比较简陋的,不合适微服务架构和集群部署。
    james122333
    james122333
    Mar 12, 2022 via Android
    10
    就是省的多写逻辑重複的 api 然后只是部分回传不同字段 一般 api 前面写个过滤器根据规则过滤一样效果 省流量倒是没有 因为你数据库是一大笔资料取出来 除非架设在一起 然而整理代码也不是不可以
    james122333
    james122333
    Mar 12, 2022 via Android
    11
    好处应该是节省 api 串接沟通成本 但其实整个结构对照并且有测试查寻页面也差不多了
    james122333
    james122333
    Mar 12, 2022 via Android
    12
    这东西其实是大而全的 涵盖不只一个功能
    虽然意义不大但要用也可以 毕竟是方案型
    不爱就是
    masterclock
    masterclock
    Mar 12, 2022
    13
    优点
    一大堆

    缺点
    说法不了:REST/JSONRPC/XXX 就行啊

    @XCFOX 主要语言对 GraphQL 的支持都很好了,
    golang 支持 dataloader ,1.8 后就有泛型 dataloader 可以用了
    golang 也支持 Apollo Federation ,另外还有个库支持 Subscription 的 federation
    Mithril
    Mithril
    Mar 12, 2022
    14
    如果你要对接的 API 消费者,不只是跟你在同一个地点工作的前端同事,他们的需求也不是你们组定的,那么 GraphQL 可以显著减少沟通成本和你自己的开发成本。
    其他情况 RESTful 能遇到的问题,GraphQL 也一样能遇到。并不会省多少事。
    但同样的,RESTful 或者瞎写的接口能做到的,GraphQL 也一样可以做。不止 NodeJS ,其他语言,至少我用过的 C#和 Java 的 Client ,功能也都很全。
    iseki
    iseki
    Mar 12, 2022
    15
    dataloader 也不能解决全部问题,只是粗暴的把 key 聚合起来一次查询而已。整体来看迁移成本太高了,将整个查询控制交给前端,前端给出啥样的查询完全不可控,很容易把后端搞死······
    reeco
    reeco
    Mar 12, 2022 via iPhone
    16
    对后端来说,这玩意除了增加工作量外没有一点好处,想不明白哪个后端会来主导用 graphql
    SjwNo1
    SjwNo1
    Mar 12, 2022
    17
    N+1 问题,其他应该都还好吧。
    ( dataloader 并不能很好地解决这个~)
    pluswu1986
    pluswu1986
    Mar 13, 2022
    18
    @iseki 被搞死。。相当于让客户端写 sql 查询 db 。。反正我们这 go 的 gqlgen 查询一复杂就经常被搞死。。。。
    ericls
    ericls
    Mar 13, 2022 via iPhone
    19
    怎么都比 restful 好
    iseki
    iseki
    Mar 13, 2022 via Android
    20
    传统 API 模式的好处是 API 相对固定,查询模式往往派生自 API ,也相对固定,便于实现和优化; graphql 这种会导致查询模式完全由前端传递,后端进行限制和优化难度陡增。想想是手动实现优化与一个 SQL 等价的查询容易还是编写一个通用的查询优化器容易~ dataloader 相对缓解这个问题,但是彻底解决我看够呛
    Weny
    Weny
    Mar 13, 2022 via iPhone
    21
    相对来说门槛高… 一般来说全栈会倾向选 graphql 。 生态也都很不错,我们在用的 urql,code-generator 可以做到前端包括小程序开发体验都是一致的。我们有一些小项目或者内部的项目,用 graphql 暴露了一套根据 entity 生成的 mongodb query dto 给到前端😂
    twocucao
    twocucao
    Mar 13, 2022
    22
    之前写过一篇文章, 结论大致是 1. 对前端来说很利好. 2. 但对后端来说, 问题蛮多的

    - View 层代码组织剧变
    - 权限问题
    - 版本更迭
    - required vs nullable vs blank
    - 服务端缓存
    - 嵌套式 API
    - N+1 问题
    - 为名所困

    https://zhuanlan.zhihu.com/p/384196319
    loading
    loading
    Mar 13, 2022
    23
    云里雾里,我选择用普通 api 方式。
    ichou
    ichou
    Mar 13, 2022 via iPhone
    24
    优点:
    没人动不动找我改 api 了

    缺点:
    太难了
    特别是 Apollo 引入的复杂度,导致在异常监控、限流、鉴权、缓存方面处理起来贼复杂
    OliveGlaze
    OliveGlaze
    Mar 13, 2022
    25
    @reeco 多少能减少一些沟通成本。我觉得沟通成本也是工作量,不只是你的代码量才是你的工作量。
    looplj
    looplj
    Mar 13, 2022
    26
    @pluswu1986 准备搞 GraphQL ,想问下为什么会有复杂查询问题,Query 应该是后端可以控制提供的吧,可以确保 Query 都走索引,前端只是控制字段扩展什么的吧。
    没有限制的话,不就是把整个 db 都暴露出去了吗
    looplj
    looplj
    Mar 13, 2022
    27
    @XCFOX Apollo 客户端一个项目,只能接一个 endpoint ?后端,准备搞点项目,用 GraphQL ,想的方案是一部分代理到已有的 GraphQL 服务,一部分新写。
    lixm
    lixm
    Mar 14, 2022
    28
    沟通成本,代码生成, 其实完全可以用 openapi 规范来实现
    GraphQL 对后端还是太不友好了
    Ayanokouji
    Ayanokouji
    OP
    Mar 18, 2022
    29
    @ZSeptember graphql 跟数据库无关吧,我理解的,比如 rest 需要查 ID ,name 俩个字段,数据库是 id ,name ,age 三个字段,通常 orm 都是这三个字段都查出来,返回两个,graphql 的逻辑处理应该跟 rest 的一样,只不过 http 的 response 只返回 id 和 name 而已
    pluswu1986
    pluswu1986
    Aug 1, 2023
    30
    @ZSeptember 没法控制客户端用各种你想不到的姿势查聚合,而且默认 go graphQL AST 解析就贼慢,普通 HTTP 接口你可以针对特定 URI 做缓存提前聚合最主要时职责清晰谁接口慢就搞谁,不该给客户端的数据就不给,GQL 查询缓存得针对查询级别的然后防不住客户端查询拉不合理的数据,一个查询可能在复杂度超标不超标边缘作死,N 个查询就是大家都不行了
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   5035 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 68ms · UTC 05:58 · PVG 13:58 · LAX 21:58 · JFK 00:58
    ♥ Do have faith in what you're doing.