缓存是将数据存储在名为 cache 的临时存储区域中的过程。当您返回到您最近访问过的页面时,浏览器可以从缓存而不是原始服务器中获取这些文件。这样可以节省您的时间,并使网络免受额外流量的负担。
与GraphQL交互的客户端应用程序负责在其末尾缓存数据。一种可能的模式是将ID等字段保留为全局唯一标识符。
在内存缓存中
InMemoryCache是GraphQL客户端应用程序中常用的规范化数据存储,而没有使用Redux等其他库。
下面给出了将InMemoryCache与ApolloClient一起使用的示例代码-
import {ApolloClient, HttpLink, InMemoryCache} from apollo-boost const cache=new InMemoryCache();const client=new ApolloClient({ link: new HttpLink(), cache });
InMemoryCache构造函数采用带有属性的可选config对象,以自定义缓存。
| Sr.No. | Parameter & Remark |
|---|---|
| 1 |
addTypename 确定是否在文档中添加__typename的布尔值(默认值:true) |
| 2 |
dataIdFromObject 一个函数,它接受数据对象并返回唯一标识符,以在规范存储中的数据时使用 |
| 3 |
fragmentMatcher 默认情况下,InMemoryCache使用启发式片段匹配器 |
| 4 |
cacheRedirects 的 在请求发生之前将查询重定向到缓存中另一个条目的函数图。 |
将在ReactJS中创建一个具有两个选项卡的单页应用程序 - 一个用于主页选项卡,另一个用于学生。 学生选项卡将从GraphQL服务器API加载数据。 当用户从主页选项卡导航到学生选项卡时,该应用程序将查询学生数据, 结果数据将由应用程序缓存。
还将使用 getTime 字段查询服务器时间,以验证页面是否已缓存,如果从缓存返回数据,则该页面将显示发送到服务器的第一个请求的时间,如果数据是对服务器的新请求的输出,它将始终显示来自服务器的最新时间。
设置服务器
以下是设置服务器的步骤-
步骤1 - 下载并安装依赖项
创建一个文件夹 cache-server-app 。从终端将目录更改为 cache-server-app 。请按照"环境设置"一章中介绍的步骤3至5进行操作。
步骤2 - 创建Schema文件
在项目文件夹 cache-server-app 中添加 schema.graphql 文件,并添加以下代码-
type Query { students:[Student] getTime:String }type Student { id:ID! firstName:String lastName:String fullName:String }
步骤3 - 添加解析器
在项目文件夹中创建一个文件resolvers.js,并添加以下代码-
const db=require(./db)const Query={ students:() => db.students.list(), getTime:() => { const today=new Date(); var h=today.getHours(); var m=today.getMinutes(); var s=today.getSeconds(); return
${h}:${m}:${s}; } } module.exports={Query}
步骤4 - 运行应用程序
创建一个server.js文件。请参阅环境设置一章中的步骤8。在终端中执行命令 npm start 。服务器将启动并在9000端口上运行。在这里,无涯教程将使用GraphiQL作为客户端来测试应用程序。
打开浏览器并输入URL http://localhost:9000/graphiql 。在编辑器中键入以下查询-
{ getTime students { id firstName } }
样本响应显示学生姓名和服务器时间。
{ "data": { "getTime": "22:18:42", "students": [ { "id": "S1001", "firstName": "Learnfk" }, { "id": "S1002", "firstName": "Kannan" }, { "id": "S1003", "firstName": "Kiran" } ] } }
设置ReactJS客户端
为客户端打开一个新终端。在执行客户端应用程序之前,服务器终端应保持运行。 React应用程序将在端口号3000上运行,服务器应用程序在端口号9000上运行。
步骤1 - 创建React应用
在客户端中,键入以下命令-
npx create-react-app hello-world-client
这将安装典型的React应用程序所需的一切。 npx实用程序和 create-react-app 工具创建一个名称为hello-world-client的项目。安装完成后,在VSCode中打开项目。
使用以下命令安装用于响应的路由器模块 npm install react-router-dom 。
步骤2 - 启动hello-world-client
将终端中的当前文件夹路径更改为hello-world-client。输入npm start启动项目。这将在端口3000上运行并将自动打开浏览器并加载索引页面。
这显示在下面给出的屏幕截图中-

步骤3 - 安装Apollo客户端库
要安装Apollo客户端,请打开一个新终端并位于当前项目文件夹路径中。键入以下命令-
npm install apollo-boost graphql
这将下载客户端的graphql库以及Apollo Boost软件包。可以通过输入npm view apollo-boost依赖项来交叉验证这一点。这将具有许多依赖关系
{ apollo-cache: ^1.1.15, apollo-cache-inmemory: ^1.2.8, apollo-client: ^2.4.0, apollo-link: ^1.0.6, apollo-link-error: ^1.0.3, apollo-link-http: ^1.3.1, apollo-link-state: ^0.4.0, graphql-tag: ^2.4.2 }
无涯教程可以清楚地看到已经安装了apollo-client库。
步骤4 - 修改App组件
对于简单的React应用程序,您只需将 index.js 保留在 src 文件夹中,并将 index.html 保留在公共文件夹中;可以删除所有其他自动生成的文件。
目录结构如下-
hello-world-client / -->node_modules -->public index.html -->src index.js students.js -->package.json
添加一个附加文件students.js,其中将包含学生组件。学生详细信息是通过"Students Component"获取的。在应用程序组件中,无涯教程正在使用HashRouter。
以下是React应用程序中的 index.js -
import React, {Component} from react; import ReactDOM from react-dom; import {HashRouter, Route, Link} from react-router-dom//components import Students from ./students class App extends Component { render() { return( <div><h1>Home !!</h1> <h2>Welcome to React Application !! </h2> </div> ) } }
function getTime() { var d=new Date(); return d.getHours()+":"+d.getMinutes()+":"+d.getSeconds() }
const routes=<HashRouter> <div> <h4>Time from react app:{getTime()}</h4> <header> <h1> <Link to="/">Home</Link> <Link to="/students">Students</Link> </h1> </header> <Route exact path="/students" component={Students}></Route> <Route exact path="/" component={App}></Route> </div> </HashRouter>
ReactDOM.render(routes, document.querySelector("#root"))
步骤5 - 在Students.js中编辑
在学生组件中,将使用以下两种方法来加载数据-
Fetch API(loadStudents_noCache)-每次单击“Student”选项卡时,都会触发一个新请求。
Apollo Client(loadWithApolloclient)-这将从缓存中获取数据。
添加函数 loadWithApolloclient ,该函数可从服务器查询学生和时间。此函数将启用缓存。在这里,使用gql函数来解析查询。
async loadWithApolloclient() { const query=gql`{ getTime students { id firstName } }`;const {data}=await client.query({query}) return data; }
获取API 是用于获取资源的简单接口。与旧的XMLHttpRequest相比,Fetch使发出Web请求和处理响应更加容易。以下方法显示了使用提取API直接加载数据-
async loadStudents_noCache() { const response=await fetch(http://localhost:9000/graphql, { method:POST, headers:{content-type:application/json}, body:JSON.stringify({query:`{ getTime students { id firstName } }`}) })const rsponseBody=await response.json(); return rsponseBody.data; }
在StudentsComponent的构造函数中,调用 loadWithApolloClient 方法。完整的 Student.js 文件在下面-
import React, {Component} from react; import { Link} from react-router-dom//Apollo Client import {ApolloClient, HttpLink, InMemoryCache} from apollo-boost import gql from graphql-tag const client=new ApolloClient({ link: new HttpLink({uri:
http://localhost:9000/graphql}), cache:new InMemoryCache() })class Students extends Component { constructor(props) { super(props); this.state={ students:[{id:1,firstName:test}], serverTime: } this.loadWithApolloclient().then(data => { this.setState({ students:data.students, serverTime:data.getTime }) }) }
async loadStudents_noCache() { const response=await fetch(http://localhost:9000/graphql, { method:POST, headers:{content-type:application/json}, body:JSON.stringify({query:
{ getTime students { id firstName } }}) }) const rsponseBody= await response.json(); return rsponseBody.data; }async loadWithApolloclient() { console.log("inside apollo client function") const query=gql
{ getTime students { id firstName } }; const {data}=await client.query({query}) return data; }render() { return( <div> <h3>Time from GraphQL server :{this.state.serverTime}</h3> <p>Following Students Found </p> <div> <ul> { this.state.students.map(s => { return( <li key={s.id}> {s.firstName} </li> ) }) } </ul> </div> </div> ) } } export default Students
步骤6 - 运行React应用程序
您可以通过从主页选项卡切换到学生选项卡来测试react应用程序。 一旦学生选项卡中加载了来自服务器的数据。 它将缓存数据。 您可以通过多次从“Home”标签切换到“Students”标签进行测试。 输出将如下所示-

如果您首先通过输入URL http://localhost:3000 /#/students 加载了学生页面,则可以看到react app和GraphQL的加载时间大致相同。之后,如果您切换到主视图并返回到GraphQL服务器,则时间不会改变。这表明数据已缓存。
步骤7 - 调用loadStudents_noCache
如果在StudentComponent的构造函数中将load方法更改为 loadStudents_noCache ,则输出将不会缓存数据。这显示了缓存和非缓存之间的区别。
this.loadStudents_noCache().then(data => { this.setState({ students:data.students, serverTime:data.getTime }) })

从上面的输出中可以明显看出,如果您在选项卡之间来回切换,那么来自graphql服务器的时间将始终是最晚的,这意味着不会缓存数据。