【问题标题】:GraphQL 有什么缺点吗? [关闭]
【发布时间】:2017-04-03 01:24:44
【问题描述】:

所有关于 GraphQL 的文章都会告诉你它有多棒,但它有什么缺点或缺点吗?谢谢。

【问题讨论】:

    标签: rest restful-authentication graphql


    【解决方案1】:

    缺点:

    • 需要学习如何设置 GraphQL。生态系统仍在快速发展,因此您必须跟上。
    • 您需要从客户端发送查询,您可以只发送字符串,但如果您想要更舒适和缓存,您将使用客户端库 -> 额外代码在您的客户端
    • 您需要事先定义架构 => 额外工作才能获得结果
    • 你需要在你的服务器上有一个 graphql 端点 => 新库你还不知道
    • Graphql 查询更多字节而不是简单地转到 REST 端点
    • 服务器需要做更多处理来解析查询并验证参数

    但是,这些不仅仅是这些:

    • GraphQL 并不难学
    • 额外的代码只有几KB
    • 通过定义架构,您将避免之后的更多工作修复错误和持久升级
    • 有很多人改用 GraphQL,因此有一个丰富的生态系统正在发展,拥有出色的工具
    • 在生产环境中使用持久查询(仅用 ID 和参数替换 GraphQL 查询)时,您实际上发送的字节比使用 REST 少
    • 传入查询的额外处理可以忽略不计
    • 提供API 和后端的干净解耦可以更快地迭代后端改进

    【讨论】:

    • “您需要事先定义架构 => 在获得结果之前需要额外的工作”我不明白如果没有 GraphQL,这怎么就没有必要了?当然,对于某些语言的某些框架,这不是必需的,但例如对于 Java API,您仍然必须在模型中描述“模式”。
    • @AntoineB 你是对的,但是在 NodeJS 中你可以很容易地制作一个 REST API,而无需考虑整体架构;只是退货。
    • @w00t 并且一旦您需要一些 REST 参数,您将求助于解析 URL 并检查参数的类型是否正确,如果不正确则抛出 400。如果只有一些东西可以避免在每个路由处理程序中手动执行此操作:D
    • 使用 Spring Boot,您只需拉一些工件 graphql-spring-boot-startergraphql-java-tools 即可开始使用。在 .graphqls 资源中创建您的架构并创建解析器类,您就完成了。启动并运行一个有效的测试示例大约需要 10 分钟。
    • 我不同意所有的缺点,事实上它可以节省你很多时间看看这篇文章xalitech.com/graphql-how-to-convince-your-boss
    【解决方案2】:

    我在 graphQL 中看到的最大问题是,如果您使用的是关系数据库,那就是 joins

    1. 您可以允许/禁止一些字段的事实使连接变得不平凡(不简单)。这会导致额外的查询。

    2. 此外,graphql 中的嵌套查询会导致循环查询,并可能使服务器崩溃。必须格外小心。

    3. 限速呼叫变得困难,因为现在用户可以在一个呼叫中触发多个查询。

    提示:使用 facebook 的数据加载器来减少 javascript/node 的查询次数

    【讨论】:

    • 1.所选字段如何与加入操作相关? 2. 如果您使用数据加载器,则不会。 3.您可以解析并分配cost给请求。如果您使用预定义的查询,客户端只发送 ID,这也不是问题。
    • 同意第 2 条。第 3 条需要额外的工作,更重要的是,人们需要注意。
    • 2.这不再是真的,因为您可以使用很多工具来保护您的服务器。例如一个链接:howtographql.com/advanced/4-security Timeouts,限制复杂性和深度。所以就像你说的一样,如果你不使用速率限制器,你的 REST 可能会被 DDoS 攻击。事情发生了变化
    • 更新点2
    【解决方案3】:

    我找到了一些重要的concerns for anyone considering using GraphQL,到目前为止,主要的几点是:

    查询不定深度:GraphQL 不能查询不定深度,所以如果你有一棵树,想在不知道深度的情况下返回一个分支,你就得做一些分页。 p>

    特定的响应结构:在 GraphQL 中,响应与查询的形状相匹配,因此如果您需要以非常特定的结构响应,则必须添加一个转换层来重塑响应.

    网络级别的缓存:由于 GraphQL 通常通过 HTTP(单个端点中的 POST)使用,因此网络级别的缓存变得困难。解决它的一种方法是使用持久查询。

    处理文件上传:GraphQL 规范中没有关于文件上传的内容,突变不接受参数中的文件。为了解决这个问题,您可以使用其他类型的 API(如 REST)上传文件,并将上传文件的 URL 传递给 GraphQL 突变,或者在执行上下文中注入文件,这样您就可以在解析器函数中拥有文件。

    不可预测的执行:GraphQL 的本质是您可以组合任何您想要的字段进行查询,但是这种灵活性并不是免费的。有一些值得了解的问题,例如性能和 N+1 查询。

    超级简单的 API:如果您的服务公开了非常简单的 API,GraphQL 只会增加额外的复杂性,因此简单的 REST API 会更好。

    【讨论】:

    • 对于无限深度,我求助于 JsonType 响应。它不是强类型的,因此您需要检查输入,但它非常方便。
    • REST 总是有 N+1 查询问题。唯一的区别是 REST 在设计上甚至不允许后端尝试解决问题。相反,它将问题推到了前端。
    • github.com/jaydenseric/graphql-multipart-request-spec - 现在广泛支持 graphql 中的文件上传
    【解决方案4】:

    每年都在变得越来越好,就目前而言,GraphQL 的community 正在增长,因此,对于之前其他答案中强调的许多问题,有更多的解决方案。 但要承认是什么仍然阻止公司将所有资源投入到 GraphQL,我想列出一些问题和解决方案,然后是未解决的问题。

    • 网络级别的缓存 - 正如Bruno 所说,它是持久查询 当然,您可以在客户端上缓存,没有人阻止您在数据库级别甚至 Redis 上使用缓存。但当然,由于 GraphQL 只有一个端点,并且每个查询都不同 - 执行这种类型的缓存比使用 REST 复杂得多。
    • GraphQL 中的嵌套查询会导致循环查询并可能导致 服务器 - 有各种各样的解决方案不再是问题。 其中一些已列出here
    • 处理文件上传 - 我们已经为它准备了 lotssolutions

    但还有更多的情况可以算作缺点:

    • 样板过多(我的意思是,对于创建例如新查询,您需要定义架构、解析器和解析器内部,以明确说明 GraphQL 如何解析您的数据和里面的字段,在客户端创建与该数据相关的字段的查询)
    • 错误处理 - 我需要说它与与 REST 的比较更相关。 apollo 在这里是可能的,但在 同时它比 REST 复杂得多
    • 身份验证和授权 - 但正如我所说,社区正在以惊人的速度增长,并且有 already couple of solutions 为了这个目标。

    总而言之,GraphQL 只是针对特定目标的工具,它肯定不是解决所有问题的灵丹妙药,当然也不能替代 REST。

    【讨论】:

      【解决方案5】:

      拥有一个端点并公开所有数据真的很棒。我发现 GraphQL 需要考虑以下几点:

      1. 文件下载/上传的实现变得棘手(转换为字符串可能不是大文件的最佳选择)
      2. 前端和后端都有大量样板和架构代码。
      3. 遵循并支持 GraphQL 规范中提供的分页。
      4. 允许自定义顺序和优先级逻辑以对字段进行排序。例如,如果我们获取用户数据以及相关的组和角色。用户可以根据用户名、组名或角色名对数据进行多重排序。
      5. 身份验证和授权将取决于后端框架。
      6. 确保后端优化和数据库支持为每个 graphql 命令触发单个查询可能会变得棘手。

      另外,应该在实施后考虑优点:

      1. 非常灵活,可以支持新项目和更新现有行为。
      2. 实施后使用参数和自定义排序轻松添加条件

      3. 使用大量自定义过滤器并摆脱所有需要创建的操作,例如用户可以将 id、name 等作为参数并执行过滤。此外,过滤器也可以应用于用户中的组。

      4. 通过创建包含所有 GraphQL 查询和突变的文件来轻松测试 API。
      5. 一旦理解了这个概念,突变就很简单,也很容易实现。
      6. 获取多个深度数据的强大方法。
      7. 对 Voyager 和 GraphiQL UI 或 Playground 的支持使其易于查看和使用。
      8. 使用有效的描述方法定义架构时易于记录。

      【讨论】:

        【解决方案6】:

        我认为目前 graphql 必须是后端架构的一部分,对于文件上传,您仍然需要使用常规 api

        【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-06-08
        • 2021-07-23
        • 2011-04-26
        • 2011-02-28
        • 2010-09-06
        • 2021-12-26
        • 2016-02-23
        相关资源
        最近更新 更多