GraphQL - 缓存存储

GraphQL - 缓存存储 首页 / GraphQL入门教程 / GraphQL - 缓存存储

缓存是将数据存储在名为 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上运行并将自动打开浏览器并加载索引页面。

这显示在下面给出的屏幕截图中-

Screenshot Browser Launch Project

步骤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。

链接:https://www.learnfk.comhttps://www.learnfk.com/graphql/graphql-caching.html

来源:LearnFk无涯教程网

以下是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”标签进行测试。 输出将如下所示-

Output React Application with NPM Start

如果您首先通过输入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
   })
})
Output React Application with loadWithApolloclient

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

祝学习愉快!(内容编辑有误?请选中要编辑内容 -> 右键 -> 修改 -> 提交!)

技术教程推荐

玩转Git三剑客 -〔苏玲〕

Swift核心技术与实战 -〔张杰〕

安全攻防技能30讲 -〔何为舟〕

后端存储实战课 -〔李玥〕

TensorFlow 2项目进阶实战 -〔彭靖田〕

Go 并发编程实战课 -〔晁岳攀(鸟窝)〕

陶辉的网络协议集训班02期 -〔陶辉〕

React Hooks 核心原理与实战 -〔王沛〕

深入拆解消息队列47讲 -〔许文强〕

好记忆不如烂笔头。留下您的足迹吧 :)