跳到主要内容位置

什么是 GraphQL?

我们前端在使用 RESTFul 形式请求后端接口数据的时候,会有下面这些问题:

  • 后端返回的数据过多,前端只用到其中一部分。
  • 后端返回的数据过少,前端需要发送多个请求到不同的 API 来组合数据。
  • 后端 API 分散,不方便统一管理数据。
  • 前后端工程师需要反复沟通 API 接口的数据结构。

为什么用 GraphQL

GraphQL 则解决了这些问题,它是一种新的 API 查询语言,使用 GraphQL,前端可以:

  • 自己决定需要哪些数据。
  • 只发送一次请求就能获得所有数据。
  • 集中提供 API ,只有一个 API 接口。
  • 前后端基本独立,后端的改动几乎不影响前端接口。

GraphQL 同时也是后端数据提供方,数据来源可以是数据库、现有 RESTful API、文件等。

GraphQL 结构

GraphQL 的结构和 JavaScript 的对象结构类似:

  • 数据是按类型组织的,例如博客类型,包含博客标题、内容等。
  • 类型中的每个属性都是强类型的,可以是 String 字符串、Int 整数、Float 浮点数,Boolean 布尔、ID 类型、数组、或者其它的自定义类型。
  • 类型之间的关系是通过嵌套来实现的,例如有博客和评论两种类型,一个博客可以有多个评论,那么就在博客类型中用一个评论类型的数组来表示这样的关系。
  • 多个类型组成了一个图状的结构,可以从一个类型找到它所有关联的类型,以及关联类型的关联类型,以此类推,不过有可能到某个类型的时候,又关联回了起始类型,形成了一个环,这在 GraphQL 中是允许的。

GraphQL 查询

再来看 GraphQL 查询数据的方法。GraphQL 服务都会内置一个网页版的查询工具,可以测试 GraphQL 语句。我们还能方便的看到有哪些类型,类型里有哪些属性,关联类型的属性等: GraphQL 查询 要查询类型中的数据,只需要在一对大括号里写上要查询的类型名,然后再用一对大括号,里边写上要查询的属性:

{
blogs {
id
title
content
}
}

如果这个属性是一个其它类型,或者由其它类型构成的数组类型,那么还需要写上要查询它里边的哪些属性,同样使用一对大括号:

{
blogs {
id
title
content
comments {
id
comment
}
}
}

如果后端 GraphQL 支持参数,用于查询符合条件的数据,这种情况下,需要使用 query 关键子定义查询的名字,然后再给支持参数的属性传递参数:

query FirstBlog {
blog(id: "1") {
title
content
}
}

在 React/Vue 中使用 GraphQL

如果要在 React 或 Vue 中使用 GraphQL,可以利用 Apollo GraphQL 这个库,它既可以用于前端查询,也可以用于创建后端 GraphQL 服务,这里快速演示一下在 Vue 中使用 Apollo GraphQL 的过程,细节可以参考相关文档,这里以 Vite 2.0 创建的 Vue 3.x 版本项目为例:

  1. 使用 npm 安装依赖库 (Node >= 14.16.0):graphql graphql-tag @apollo/client @vue/apollo-composable
yarn add graphql graphql-tag @apollo/client @vue/apollo-composable
  1. 安装之后配置 GraphQL 客户端,指定 GraphQL 地址等信息,这里代码如果没有特殊需要,只需要关心 graphql 的 uri:
// src/apolloClient.js
import {
ApolloClient,
createHttpLink,
InMemoryCache,
} from "@apollo/client/core";

const httpLink = createHttpLink({
uri: "http://localhost:4000/graphql",
});

const cache = new InMemoryCache();

const apolloClient = new ApolloClient({
link: httpLink,
cache,
});

export default apolloClient;
  1. 之后利用 provide,和 apollo 提供的工具,把 Graphql 客户端加载到 Vue 应用中:
// src/main.js
import { createApp, provide, h } from "vue";
import { DefaultApolloClient } from "@vue/apollo-composable";
import App from "./App.vue";
import apolloClient from "./apolloClient";

createApp({
setup() {
provide(DefaultApolloClient, apolloClient);
},
render: () => h(App),
}).mount("#app");
  1. 在组件中利用内置的 gql 库编写 GraphQL 语句,并使用 ApolloGraphQL 提供的 useQuery 查询 API:
<script setup>
import { useQuery } from "@vue/apollo-composable";
import { gql } from "graphql-tag";

const { result, loading } = useQuery(gql`
query AllBlogs {
blogs {
id
title
content
}
}
`);
</script>
  1. 模板中展示结果,根据 loading 值显示加载状态,根据 result 显示内容:
<template>
<div v-if="loading">loading...</div>
<ul v-else>
<li v-for="blog in result.blogs" :key="blog.id">
{{ blog.title }} - {{ blog.content }}
</li>
</ul>
</template>

小结

好了,这个就是 GraphQL 的简介和使用方法,你学会了吗?如果有帮助请三连,想学更多有用的前端开发知识,请关注峰华前端工程师,感谢观看!