使用Apollo创建GraphQL Service

安装

perl 复制代码
"@apollo/client": "^3.7.1",
"graphql": "^16.6.0",

@apollo/client: 这是Apollo Client的JavaScript库,用于在前端应用中管理GraphQL请求。Apollo Client是一个现代化的GraphQL客户端,它提供了强大的功能,包括数据缓存、实时更新、错误处理等。通过Apollo Client,你可以轻松地向GraphQL服务器发出查询和变更请求,并将响应的数据集成到你的前端应用中。版本号^3.7.1表示你的应用使用的是3.7.1版本的Apollo Client库。

graphql: 这是GraphQL查询语言的JavaScript解析器。GraphQL是一种用于API的查询语言,它允许客户端明确指定需要的数据结构,从而避免了传统REST API中可能存在的数据过载问题。GraphQL库提供了解析GraphQL查询字符串、验证查询的结构等功能。版本号^16.6.0表示你的应用使用的是16.6.0版本的GraphQL库。

这两个库的结合使用, @apollo/client用于发送和管理GraphQL请求,而graphql库则用于解析和验证GraphQL查询语言。在前端应用中,你可以使用Apollo Client来构建和发送GraphQL查询,并使用graphql库来解析从服务器返回的GraphQL响应。这样,你可以通过GraphQL与服务器进行灵活、高效的数据交互,而这两个库的版本号则表示你所使用的具体版本。

vite 支持 eslint

pnpm i vite-plugin-eslint -D

vite-plugin-eslint 是 Vite 构建工具的一个插件,用于集成 ESLint 到 Vite 项目中.

  • 代码质量检查: vite-plugin-eslint 可以帮助开发者在构建过程中对项目代码进行静态代码分析,以发现潜在的问题、代码风格不一致或错误。ESLint 是一个常用的 JavaScript/TypeScript 代码质量检查工具,它提供了大量的规则,用于检测和修复代码。
  • 自动修复: 除了检查代码,该插件还支持自动修复一些 ESLint 可以处理的问题。通过配置,它可以自动修复一些简单的代码问题,提高开发效率。
  • 集成到构建流程: vite-plugin-eslint 能够与 Vite 构建流程集成,确保在开发和生产环境中都能进行代码检查。这有助于在代码提交前或构建过程中发现潜在的问题,提高代码质量。

实现 graphql service 层

pnpm i @apollo/client graphql -S

初始化Apollo Client

新建utlis文件夹,以及apollo.ts,创建Apollo客户端实例。

javascript 复制代码
import { ApolloClient, InMemoryCache } from '@apollo/client';

export const client = new ApolloClient({
  uri: 'http://localhost:3000/graphql',
  cache: new InMemoryCache(),
});

import { ApolloClient, InMemoryCache } from '@apollo/client';: 这行代码引入了Apollo Client库中的ApolloClient和InMemoryCache两个类。ApolloClient用于创建一个Apollo客户端实例 ,而InMemoryCache是用于客户端内部缓存数据的缓存实现。

InMemoryCache 是 Apollo Client 提供的一种缓存实现,它用于在客户端内部缓存GraphQL查询的响应数据。这个缓存实现的主要作用是在客户端内存中维护一个数据存储,将从服务器获取的数据响应保存在内存中。当应用程序执行相同的GraphQL查询时,它会首先检查内存缓存中是否已经有了该查询的响应数据,如果有则直接返回缓存中的数据,避免了不必要的网络请求。

以下是 InMemoryCache 的主要特性和作用:

  • 缓存响应数据: 当应用程序发起GraphQL查询时,InMemoryCache 会将查询的响应数据缓存到内存中。这包括了查询的具体结果以及相应的数据标识(例如ID)。
  • 智能合并数据: 当多个组件发起相同查询时,InMemoryCache 会智能地将这些查询的响应数据进行合并。它使用数据标识(通常是ID)来判断哪些数据是相同的,从而避免了数据的冗余存储。
  • 快速读取数据: 由于数据保存在内存中,所以从缓存中读取数据非常迅速。这减少了应用程序的加载时间,提高了性能。
  • 减少网络请求: 通过在客户端内部缓存数据,可以减少对服务器的网络请求。只有在缓存中没有找到数据时,客户端才会向服务器发起请求。
  • 自动化的数据更新: 当应用程序修改了缓存中的数据,InMemoryCache 会自动通知相关的查询组件,以便它们可以重新渲染,并显示最新的数据。

总的来说,InMemoryCache 是 Apollo Client 的核心之一,它帮助应用程序有效地管理和利用从服务器获取的数据,提供了一种高效的方式来处理GraphQL查询的响应数据。

export const client = new ApolloClient({ uri: 'http://localhost:3000/graphql', cache: new InMemoryCache(), });: 这部分代码创建了一个新的Apollo客户端实例。在这个实例中,你配置了两个主要的参数:

  • uri: 'http://localhost:3000/graphql': 这个参数指定了GraphQL服务器的URL。Apollo Client将会向这个URL发送所有的GraphQL请求。在这个例子中,GraphQL服务器位于本地机器的端口3000上的'/graphql'路径。
  • cache: new InMemoryCache(): 这个参数指定了客户端的缓存实现。InMemoryCache是Apollo Client提供的一种缓存策略,它将在客户端内部缓存GraphQL查询的响应数据,以便在后续的查询中使用。通过使用缓存,可以避免不必要的网络请求,提高应用性能。

export const client: 最后,通过export关键字将创建好的Apollo客户端实例导出,使得其他文件可以引入并使用这个客户端实例来发送GraphQL请求。

总的来说,这段代码的作用是创建了一个Apollo Client实例,配置了GraphQL服务器的URL和缓存策略,使得你的前端应用可以使用这个客户端实例来与GraphQL服务器进行数据交互。

2.包裹ApolloProvider

javascript 复制代码
import React from 'react';
import ReactDOM from 'react-dom/client';
import { ApolloProvider } from '@apollo/client';
import App from './App';
import './index.css';
import { client } from './utils/applo';

ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
  <ApolloProvider client={client}>
    <App />
  </ApolloProvider>,
);

import { ApolloProvider } from '@apollo/client';: 这行代码引入了Apollo Client库中的ApolloProvider组件。ApolloProvider是Apollo Client提供的React组件,它用于将Apollo Client的实例传递给React应用的组件树,以便应用程序中的组件可以发起GraphQL查询。

import { client } from './utils/applo';: 这行代码引入了应用程序中用于与GraphQL服务器交互的Apollo Client实例,通常从./utils/applo文件中导出。

<ApolloProvider client={client}>, <App />: 这部分代码使用ApolloProvider组件包裹了应用程序的主组件。ApolloProvider组件接受一个client属性,该属性传递了应用程序与GraphQL服务器通信的Apollo Client实例。通过ApolloProvider,整个应用程序的组件树都可以访问到Apollo Client,可以发起GraphQL查询请求。

通过这段代码,整个React应用程序得以和Apollo Client连接,使得应用程序能够方便地发起GraphQL查询请求,并且将查询的数据集成到React组件中,实现前端与GraphQL服务器的数据交互。

3.定义gql schema

创建文件夹

javascript 复制代码
import { gql } from '@apollo/client';

export const FIND = gql`
query find($id: String!){
    find(id: $id){
          name
      desc
    }
  }
`;

这段代码使用了Apollo Client库中的gql函数,它用于定义GraphQL查询。

import { gql } from '@apollo/client';: 这行代码引入了Apollo Client库中的gql函数。gql函数是一个用于解析GraphQL查询字符串的函数,它可以将一个字符串转换为GraphQL AST(Abstract Syntax Tree)。

`` export const FIND = gql...` ```: 这部分代码定义了一个GraphQL查询。在这个例子中,定义了一个名为FIND的GraphQL查询,它使用GraphQL模板字符串的语法,包裹了一个具体的查询字符串。这个查询的目的是根据提供的id参数查询特定用户的name和desc字段。

中间的代码可以在GraphQL调试面板复制

javascript 复制代码
query find($id: String!){
find(id: $id){
name
desc
}
}

query find($id: String!): 这行代码定义了一个GraphQL查询操作,命名为find。它接受一个名为id的参数,类型为字符串,表示要查询的用户的唯一标识。$id: String!中的!表示该参数是必需的。

{ find(id: $id) { name desc } }: 这部分代码指定了查询的具体操作。在find操作中,传入了id参数,并请求返回用户的name和desc字段。这里的name和desc是假设用户对象中包含的字段名。

4.使用useQuery,useMutation

在App.tsx中编写,

此时

javascript 复制代码
import { useQuery } from '@apollo/client';
import './App.css';
import { FIND } from './graphql/demo';

const App = () => {
  const { loading, data } = useQuery(FIND, {
    variables: {
      id: '22820297-e288-42ba-aadf-3a4062c5c3cb',
    },
  });
  return (
    <div>
      <p>
        data:
        {JSON.stringify(data)}
      </p>
      <p>{`${loading}`}</p>
    </div>
  );
};
export default App;

上述代码使用了Apollo Client中的useQuery hook,它是一个用于在React函数组件中执行GraphQL查询的钩子函数。

import { useQuery } from '@apollo/client';: 这行代码引入了Apollo Client库中的useQuery hook。useQuery hook允许在React函数组件中执行GraphQL查询,并处理查询的结果(例如加载状态、查询数据等)。

import { FIND } from './graphql/demo';: 这行代码引入了之前定义的GraphQL查询FIND。这个查询通常包含在一个单独的文件中(例如demo.js),然后被引入到应用程序中。

const { loading, data } = useQuery(FIND, { variables: { id: '22820297-e288-42ba-aadf-3a4062c5c3cb', }, });: 这行代码使用useQuery hook来执行GraphQL查询。useQuery接受两个参数:第一个参数是之前定义的GraphQL查询(在这里是FIND),第二个参数是一个对象,用于传递查询的变量(如果有的话)。

  • loading: 这是一个布尔值,表示查询是否仍在加载中。当loading为true时,表示查询尚未完成。
  • data: 这是包含查询结果的对象。当查询完成后,data中将包含从服务器返回的数据。

useQuery hook负责在组件挂载时(或者在查询变量发生变化时)发起GraphQL查询,并将查询的结果返回给组件。variables选项中指定了查询所需的变量,例如id的值。

通过这种方式,App组件可以根据loading状态显示加载指示器,然后使用data中的数据来渲染应用程序的UI,从而实现了与GraphQL服务器的数据交互和渲染。

运行结果如下:

具体的网络请求信息如下


视频插播

开启跨域限制:

javascript 复制代码
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.enableCors();
  await app.listen(3000);
}
bootstrap();

如果想允许部分地址可以跨域,需要这么写:

也可以配置的允许跨域的域名:

css 复制代码
app.enableCors({
   origin: 'http://localhost:5173',
});

编写update操作(使用useMutation)

编写对应的gql语句,定义了一个 GraphQL 变更(Mutation)查询,使用了 Apollo Client 提供的 gql 模板字符串。

php 复制代码
export const UPDATE = gql`
mutation update($id: String!, $params: UserInput!){
  update(id: $id, params: $params)
}
`;

```export const UPDATE = gql...`````: 这行代码定义了一个 GraphQL 变更操作,命名为 UPDATE。gql 函数用于将 GraphQL 查询字符串转换为 GraphQL AST(Abstract Syntax Tree),以便 Apollo Client 可以理解和发送到服务器。

mutation update($id: String!, $params: UserInput!): 这部分定义了一个 GraphQL 变更操作,命名为 update。它接受两个参数:$id(一个字符串)和 $params(一个类型为 UserInput 的输入对象)。这些参数是在调用这个变更操作时必须提供的, <math xmlns="http://www.w3.org/1998/Math/MathML"> i d 表示要更新的用户的唯一标识,而 id 表示要更新的用户的唯一标识,而 </math>id表示要更新的用户的唯一标识,而params 包含了更新用户时所需的各种属性(例如 name、email 等)。

update(id: $id, params: $params): 在变更操作的主体部分。

id: $id 表示使用传入的 $id 参数作为用户的唯一标识,

params: $params 表示使用传入的 $params 参数作为要更新的用户的属性。

<math xmlns="http://www.w3.org/1998/Math/MathML"> i d 和 id 和 </math>id和params是通过 Mutation 操作的参数传递给后端的实际值 。 <math xmlns="http://www.w3.org/1998/Math/MathML"> i d 对应了前面定义的 id 对应了前面定义的 </math>id对应了前面定义的id 输入参数, <math xmlns="http://www.w3.org/1998/Math/MathML"> p a r a m s 对应了 params 对应了 </math>params对应了params 输入参数。

这里的 update 是一个 GraphQL 变更(Mutation)操作的名称。在 GraphQL 中,update 是一个被服务器端实现的 Mutation 操作,用于执行数据的更新。

在前端应用程序中使用 Apollo Client 的 useMutation hook 方法时,需要提供一个包含相同变更操作名称(比如 update)的 Mutation 查询。这样,Apollo Client 就知道在发送请求时要将数据传递给服务器上名为 update 的变更操作。

在代码中,UPDATE 是一个 GraphQL 查询,它定义了一个名为 update 的 Mutation 操作。当你在前端应用程序中调用 useMutation hook时,你将使用这个 UPDATE 查询。例如,使用 useMutation hook 的方式可能如下:

这样定义了一个 GraphQL 变更查询后,可以在前端应用程序中使用 Apollo Client 的 useMutation hook 来执行这个变更操作,将更新的数据发送给服务器。这个查询使得前端应用程序能够与服务器进行双向数据交互,实现了数据的更新功能。

调用useMutation,返回update函数

sql 复制代码
import { FIND, UPDATE } from './graphql/demo';
const [update] = useMutation(UPDATE);

const [update] = useMutation(UPDATE);: 这行代码使用了useMutation hook,它是Apollo Client提供的一个React hook,用于执行GraphQL变更操作。在这里,useMutation hook接受了UPDATE变更操作作为参数,并返回一个数组,其中包含了一个函数(在这里命名为update)和其他一些属性。

update: 这是一个函数,用于触发GraphQL变更操作 。在这个例子中,它被赋值给[update]的左侧,表示我们只关心返回的第一个函数。当调用update函数时,它将发送UPDATE变更操作的请求到GraphQL服务器。你可以通过传递变更操作所需的参数来执行相应的数据更新。

总的来说,这段代码的作用是使用useMutation hook,将从'./graphql/demo'导入的UPDATE变更操作绑定到一个函数update上。这个函数可以在组件中被调用,用于触发GraphQL服务器上的相应数据更新操作。

编写按钮的事件监听函数,参数可以从Graph调试面板中复制,

php 复制代码
const onClickHandler = () => {
    update({
      variables: {
        id: '22820297-e288-42ba-aadf-3a4062c5c3cb',
        params: {
          desc,
          name,
        },
      },
    });
  };

update({ variables: { id: '22820297-e288-42ba-aadf-3a4062c5c3cb', params: { desc, name, }, }, });: 在onClickHandler函数中,update函数被调用,触发了GraphQL变更操作。这个操作的目的通常是将某个对象的属性更新为特定的值。

variables: { id: '22820297-e288-42ba-aadf-3a4062c5c3cb', params: { desc, name, }, },: 这是一个包含变更操作所需参数的对象。id参数是一个字符串,表示要更新的对象的唯一标识符。params参数是一个对象,包含了两个属性desc和name,它们的值通常来自于组件中的状态或者用户的输入。

update函数是之前使用useMutation hook从UPDATE变更操作中获得的。通过调用update函数并传入包含了所需参数的对象,GraphQL客户端将向服务器发起一个GraphQL变更请求,执行相应的操作。

最终效果如下:

执行后具体的网络请求信息

相关推荐
XiaoYu20021 小时前
第3章 Nest.js拦截器
前端·ai编程·nestjs
自己的九又四分之三站台18 小时前
导入数据到OG GraphQL以及创建graph
java·后端·graphql
XiaoYu20021 天前
第2章 Nest.js入门
前端·ai编程·nestjs
实习生小黄2 天前
NestJS 调试方案
后端·nestjs
当时只道寻常5 天前
NestJS 如何配置环境变量
nestjs
咨询qq 87622396514 天前
一种增强的独立分量分析方法-基于小波域(MATLAB R2018B) 压缩包=数据+代码+参考...
graphql
濮水大叔17 天前
VonaJS是如何做到文件级别精确HMR(热更新)的?
typescript·node.js·nestjs
Tadas-Gao17 天前
GraphQL:下一代API架构的设计哲学与实践创新
java·分布式·后端·微服务·架构·graphql
ovensi17 天前
告别笨重的 ELK,拥抱轻量级 PLG:NestJS 日志监控实战指南
nestjs