开发手册 欢迎您!
软件开发者资料库

GraphQL - 缓存

GraphQL缓存 - 从简单和简单的步骤学习GraphQL,从基本到高级概念,包括简介,环境设置,体系结构,应用程序组件,示例,类型系统,架构,解析器,查询,变异,验证,JQuery集成,React集成, Apollo客户端,身份验证客户端,缓存。

缓存是将数据存储在名为缓存的临时存储区域中的过程.当您返回到最近访问过的页面时,浏览器可以从缓存而不是原始服务器获取这些文件.这节省了您的时间和网络,增加了额外流量的负担.

与GraphQL交互的客户端应用程序负责在其末端缓存数据.一种可能的模式是将字段(如id)保留为全局唯一标识符.

InMemory Cache

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构造函数接受一个带有属性的可选配置对象来自定义缓存.

Sr.No.参数&说明
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 : 创建架构

在项目文件夹 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": "Mohtashim"         },         {            "id": "S1002",            "firstName": "Kannan"         },         {            "id": "S1003",            "firstName": "Kiran"         }      ]   }}

设置ReactJS客户端

打开一个客户的新终端.在执行客户端应用程序之前,服务器终端应保持运行. React应用程序将在端口号3000上运行,服务器应用程序在端口号9000上运行.

步骤1和减号;创建React应用程序

在客户端终端中,键入以下命令 :

npx create-react-app hello-world-client

这将安装典型反应应用程序所需的一切. npx实用程序 create-react-app 工具创建一个名为hello-world-client的项目.安装完成后,在VSCode中打开项目.

使用以下命令安装路由器模块以进行响应 -   npm install react-router-dom .

第2步和第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 dependencies来交叉验证.这将有许多依赖关系,如下所示 :

{    '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 : 修改index.js文件中的App组件

对于简单的反应应用程序,您只需要将 index.js 保留在 src 公用文件夹中的文件夹和 index.html ;可以删除自动生成的所有其他文件.

目录结构在下面和下面给出;

hello-world-client /   -->node_modules   -->public      index.html   -->src      index.js      students.js   -->package.json

添加一个包含Students Component的附加文件students.js.学生详细信息通过学生组件获取.在App Component中,我们使用的是HashRouter.

以下是反应应用中的 index.js :

import React, {Component} from 'react';import ReactDOM from 'react-dom';import {HashRouter, Route, Link} from 'react-router-dom'//componentsimport Students from './students'class App extends Component {   render() {      return(         

Home !!

         

Welcome to React Application !! 

         
      )   }}function getTime() {   var d = new Date();   return d.getHours()+":"+d.getMinutes()+":"+d.getSeconds()}const routes =    
      

Time from react app:{getTime()}

      
         

  Home          Students  

      
               
ReactDOM.render(routes, document.querySelector("#root"))

Step 5 : 编辑Students.js中的组件学生

在学生组件中,我们将使用以下两种方法来加载数据 :

  • 获取API(loadStudents_noCache) : 这会在每次点击学生标签时触发新请求.

  • Apollo Client(loadWithApolloclient) : 这将从缓存中获取数据.

添加一个函数 loadWithApolloclient 从服务器查询学生和时间.此功能将启用缓存.这里我们使用gql函数来解析查询.

async loadWithApolloclient() {   const query = gql`{      getTime      students {         id         firstName      }   }`;   const {data} = await  client.query({query})   return data;}

Fetch API 是一个用于获取资源的简单界面.与旧的XMLHttpRequest相比,Fetch使Web请求和处理响应变得更容易.以下方法显示使用fetch 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 Clientimport {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(         
            

Time from GraphQL server :{this.state.serverTime}

            

Following Students Found 

            
               
                      {                     this.state.students.map(s => {                        return(                                                         {s.firstName}                                                   )                     })                  }               
            
         
      )   }}export default Students

步骤6 : 去;使用 npm start 运行React应用程序

您可以通过从主页选项卡切换到学生选项卡来测试反应应用程序.一旦学生选项卡加载了来自服务器的数据.它将缓存数据.您可以通过多次从home切换到student选项卡来测试它.输出将如下所示 :

输出反应应用程序与NPM开始

如果您通过输入URL http://localhost:3000/#/students 首先加载了学生页面,您可以看到react app和GraphQL的加载时间大致相同相同.之后,如果切换到主视图并返回到GraphQL服务器,则时间不会更改.这表示数据已缓存.

步骤7 : 更改loadWithApolloclient调用loadStudents_noCache

如果在StudentComponent的构造函数中将load方法更改为 loadStudents_noCache ,则输出将不会缓存数据.这显示了缓存和非缓存之间的区别.

this.loadStudents_noCache().then(data => {   this.setState({      students:data.students,      serverTime:data.getTime   })})

使用loadWithApolloclient输出React应用程序

从上面的输出可以看出,如果你来回切换在选项卡之间,来自graphql server的时间总是最新的,这意味着数据不会被缓存.