5 分钟内理解 GraphQL

2025-06-09

5 分钟内理解 GraphQL

GraphQL 一经推出便迅速在互联网上迅速传播,如同流行病般蔓延。GraphQL 彻底改变了人们的工作方式,并将继续在各个领域持续发展。如果您有五分钟时间,我将为您详细讲解所有您需要了解的内容。

曾几何时

到2012年,全球手机普及率已达到惊人的水平。这股入侵浪潮席卷全球,那些未能及时调整自身产品的公司将面临风险。当时,Facebook 就面临风险。

Facebook 主要是一家网络公司。因此,他们使用 web-view 将其 iOS 应用做得像个网站。很快,他们意识到 web-view 当时很糟糕。于是,他们决定完全用原生应用重做,以提供更好的用户体验。然而,他们很快就遇到了另一个瓶颈。

现有架构无法正常工作。主要是因为现有 REST API 的端点无法灵活处理数据。嵌套数据需要多次往返不同的端点,导致速度缓慢且不一致。大多数查询不需要部分有效负载,从而导致不必要的数据传输。最重要的是,处理如此多的 HTTP 调用对 Facebook 来说非常繁琐。

就在这种恶劣的环境下,2012年2月,Lee ByronDan SchaferNick Schrock在 Facebook 的一个角落里预定了一些工作站。

很快,我们的三位开发人员就开发出了 GraphQL 的第一个原型,当时名为 SuperGraph。2012 年 8 月,GraphQL 随新的 Facebook 原生应用投入生产。2015 年,第一个公开版本在互联网上发布。如今,当你浏览 Facebook 信息墙时,GraphQL 依然清晰可见。但他们是如何解决这个不仅影响 Facebook,而且影响整个行业的问题的呢?

什么是 GraphQL?

GraphQL 是一种用于 API 的数据查询语言。QL 与 SQL 类似,代表查询语言 (Query Language)。GraphQL允许以简单、灵活且非常精确的方式操作数据。GraphQL既不是编程语言,也不是框架。GraphQL 是一种实现 API 的规范。具体来说,它看起来像这样。

要求

{
    pokemons {
        name,
        abilities {
          name,
          damage,
          accuracy,
          mana,
          type
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

回复

{
    "data": {
        "pokemons": \[
            {
                "name": "pikachu",
                "abilities": \[
                    {
                        "name": "Thunder punch",
                        "damage": 75,
                        "accuracy": 70,
                        "mana": 15,
                        "type": "physical"
                    },
                    {
                        "name": "Thunderbolt",
                        "damage": 90,
                        "accuracy": 80,
                        "mana": 15,
                        "type": "electric"
                    }
                \]
            },
            {
                "name": "mewtwo",
                "abilities": \[
                     {
                        "name": "Earthquake",
                        "damage": 130,
                        "accuracy": 100,
                        "mana": 20,
                        "type": "ground"
                    },
                    {
                        "name": "Brutal swing",
                        "damage": 180,
                        "accuracy": 90,
                        "mana": 25,
                        "type": "physical"
                    }
                \]
            }
        \]
    }
}
Enter fullscreen mode Exit fullscreen mode

这就是使用 GraphQL 请求和接收数据的方式。好的,目前还不清楚。首先,这个东西在你的架构中处于什么位置?

那个笑着的家伙就是你。要制作我之前展示的包含宝可梦及其技能的payload,你可就麻烦了。你之所以费劲,是因为你使用的REST API并不符合你的需求。你最终只能为每个宝可梦调用一次,然后为每个宝可梦的技能调用一次。

每次应用程序中的逻辑都会向数据库发出请求并发送有效负载。因此,尽管你表面上笑着,但内心却很想自杀。这就是 GraphQL 的用武之地。

有了 GraphQL,问题就不再存在。您只需发起一个 POST 请求,即可通过 GraphQL 请求明确告知所需信息。之后,服务器将管理一切,您即可获得完整的负载。

使用 REST,你可以获得由端点定义的对象。使用 GraphQL,你无需适应后端定义的对象,而是可以动态定义要在客户端接收的对象。这改变了一切。

好吧,这一切都很好,但它具体是如何工作的呢?GraphQL 如何访问数据库并进行查询?要真正理解 GraphQL,你必须亲手实践。

显示代码

我将为你创建一个 JavaScript 实现(NodeJS)。请注意,以下所有内容适用于任何语言。GraphQL逻辑在任何地方都保持不变,因为它首先是一个规范。

要开始使用 GraphQL,请访问官方网站及其全球所有语言的实现列表。为了简化 NodeJS 的使用,我们需要 express-graphql 和 graphql 模块。让我们从安装基础服务器开始。

index.js

const path = require("path");
const express = require("express");
const graphqlHTTP = require("express-graphql");
const graphql = require("graphql");

const { query } = require(path.resolve("schema/query"));
const graphQLSchema = new graphql.GraphQLSchema({ query });

const app = express();

app.use(
  "/graphql",
  graphqlHTTP({
    schema: graphQLSchema,
    graphiql: true
  })
);

app.listen(8080);
Enter fullscreen mode Exit fullscreen mode

首先,我们调用依赖项。然后在第 6 行查找根查询,并在第 7 行将其传递给主模式。我们启动 Express 服务器,通过 Express 中间件暴露 /graphql 路由,最后监听 8080 端口。现在让我们看看模式内部发生了什么。

模式/query.js

const path = require("path");
const { GraphQLObjectType, GraphQLList } = require("graphql");
const { pokemonsType } = require(path.resolve("schema/types"));

const RootQuery = new GraphQLObjectType({
  name: "RootQueryType",
  type: "Query",
  fields: {
    pokemons: {
      type: new GraphQLList(pokemonsType),
      resolve() {
        const data = require(path.resolve("data/pokemons.json"));

        return data;
      }
    }
  }
});

exports.query = RootQuery;
Enter fullscreen mode Exit fullscreen mode

Schema 是 GraphQL 的核心。它将决定客户端和服务器之间的通信方式。它指定了客户端可以执行的查询、可以检索的数据类型以及这些类型之间的关系。 * 所有内容都定义在此 Schema 中。从根查询开始。

根查询允许 GraphQL 知道可以检索什么类型的数据。在这里,在我的根查询中,我指定了字段 pokemon 第 9 行,它是一个 pokemon 类型的列表(第 10 行)。

然后我们在第 11 行有一个解析器。解析器负责从数据库获取数据。每个字段都会分配一个解析器。我的 pokemon 字段的解析器是一个 pokemon 对象列表。我的解析器通过一个 JSON 文件返回数据,该文件对应于一个 pokemon 数组。

为了简洁起见,我返回的是 JSON 格式的数据。但在实际应用中,你应该调用数据库,进行查询,然后返回数据。现在我们来看看 JSON 格式的数据是什么样的。

模式/types.js

const path = require("path");
const graphql = require("graphql");
const { GraphQLObjectType, GraphQLString, GraphQLList } = graphql;

const abilitiesType = new GraphQLObjectType({
  name: "ability",
  fields: {
    name: {
      type: GraphQLString,
      resolve: parent => parent.name
    },
    damage: {
      type: GraphQLString,
      resolve: parent => parent.damage
    },
    accuracy: {
      type: GraphQLString,
      resolve: parent => parent.accuracy
    },
    mana: {
      type: GraphQLString,
      resolve: parent => parent.mana
    },
    type: {
      type: GraphQLString,
      resolve: parent => parent.type
    }
  }
});

const pokemonsType = new GraphQLObjectType({
  name: "pokemons",
  fields: {
    name: {
      type: GraphQLString,
      resolve: parent => parent.name
    },
    abilities: {
      type: new GraphQLList(abilitiesType),
      resolve(parent) {
        const abilities = require(path.resolve("data/abilities.json"));

        return abilities.filter(ability =>
          ability.linkedTo.includes(parent.name)
        );
      }
    }
  }
});

exports.pokemonsType = pokemonsType;
Enter fullscreen mode Exit fullscreen mode

原理保持不变。我们创建代表数据结构的 GraphQL 对象类型。我们指定字段,并为每个字段分配一个解析器来查找正确的数据。有趣的是,我在这里使用父级的上下文来过滤要为每个宝可梦返回哪些能力(第 44 行)。

如果你想查看这个实现的实际版本,我创建了一个小型公共沙盒,你可以在里面试用。你可以看到所有文件,包括 JSON 文件,并且可以随意更改!

除了 JSON 数据,你也可以通过在 PokéAPI 上执行 fech 来实现同样的功能。这样你也能练习 GraphQL 了。

结语

就这样吧,我的演示就到此为止了。我已经超过了你给我的五分钟时间。关于这项技术还有很多内容可以讲。比如突变、缓存、变量和上下文。我会先讲讲基础知识。如果你想了解更多,并且有空闲时间,我推荐你阅读这篇非常完整的文章

鏂囩珷鏉ユ簮锛�https://dev.to/jesuisundev/understand-graphql-in-5-minutes-1oa6
PREV
你笑你就输了 使用 Javascript AI 你笑你就输了 安装配置启动
NEXT
一些有用的.NET项目库