Кэширование — это процесс хранения данных во временной области хранения, называемой кешем . Когда вы возвращаетесь на страницу, которую вы недавно посещали, браузер может получать эти файлы из кэша, а не с исходного сервера. Это экономит ваше время и сеть от бремени дополнительного трафика.
Клиентские приложения, взаимодействующие с 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 Карта функций для перенаправления запроса на другую запись в кеше до его выполнения. |
addTypename
Логическое значение, определяющее, следует ли добавлять __typename в документ (по умолчанию: true)
dataIdFromObject
Функция, которая принимает объект данных и возвращает уникальный идентификатор, который будет использоваться при нормализации данных в хранилище.
fragmentMatcher
По умолчанию InMemoryCache использует эвристический алгоритм сопоставления фрагментов.
cacheRedirects
Карта функций для перенаправления запроса на другую запись в кеше до его выполнения.
иллюстрация
Мы создадим одностраничное приложение в ReactJS с двумя вкладками — одна для домашней вкладки и другая для студентов. Вкладка студентов будет загружать данные из API сервера GraphQL. Приложение будет запрашивать данные о студентах, когда пользователь переходит с домашней вкладки на вкладку студентов. Полученные данные будут кэшироваться приложением.
Мы также запросим время сервера, используя поле getTime, чтобы проверить, кэширована ли страница. Если данные возвращаются из кэша, на странице будет отображаться время самого первого запроса, отправленного на сервер. Если данные являются результатом нового запроса к серверу, он всегда будет показывать самое последнее время с сервера.
Настройка сервера
Ниже приведены шаги для настройки сервера:
Шаг 1 — Загрузите и установите необходимые зависимости для проекта
Создайте папку cache-server-app . Измените свой каталог на кеш-сервер-приложение из терминала. Выполните шаги с 3 по 5, описанные в главе «Настройка среды».
Шаг 2 — Создание схемы
Добавьте файл schema.graphql в папку проекта cache-server-app и добавьте следующий код —
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-реагировать на приложение создают проект с именем hello-world-client. После завершения установки откройте проект в VSCode.
Установите модули маршрутизатора для реакции, используя следующую команду — npm install response-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. Изменение компонента приложения в файле index.js
Для простого приложения реагирования вам нужно только сохранить index.js в папке src и index.html в общей папке; все остальные файлы, которые создаются автоматически, могут быть удалены.
Структура каталогов приведена ниже —
hello-world-client / -->node_modules -->public index.html -->src index.js students.js -->package.json
Добавьте дополнительный файл student.js, который будет содержать компонент Students. Сведения об ученике извлекаются через компонент ученика. В компоненте приложения мы используем HashRouter.
Ниже приводится 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) — это будет запускать новый запрос каждый раз, когда нажимает вкладку ученика.
-
Клиент Apollo (loadWithApolloclient) — будет извлекать данные из кэша.
Fetch API (loadStudents_noCache) — это будет запускать новый запрос каждый раз, когда нажимает вкладку ученика.
Клиент Apollo (loadWithApolloclient) — будет извлекать данные из кэша.
Добавьте функцию loadWithApolloclient, которая запрашивает студентов и время с сервера. Эта функция включит кеширование. Здесь мы используем функцию gql для разбора запроса.
async loadWithApolloclient() { const query = gql`{ getTime students { id firstName } }`; const {data} = await client.query({query}) return data; }
Fetch API — это простой интерфейс для извлечения ресурсов. Fetch облегчает создание веб-запросов и обработку ответов, чем при использовании более старого XMLHttpRequest. Следующий метод показывает загрузку данных напрямую с помощью 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 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 с npm start
Вы можете протестировать приложение реагирования, переключившись с домашней вкладки на вкладку студентов. После того, как вкладка студентов загружается с данными с сервера. Это будет кешировать данные. Вы можете проверить это, переключаясь из дома на вкладку студентов несколько раз. Вывод будет таким, как показано ниже —
Если вы сначала загрузили страницу учеников, введя URL-адрес http: // localhost: 3000 / # / Students, вы увидите, что время загрузки приложения реагировать и GraphQL будет примерно одинаковым. После этого, если вы переключитесь в режим домашнего просмотра и вернетесь на сервер GraphQL, время не изменится. Это показывает, что данные кэшируются.
Шаг 7 — Измените вызов loadWithApolloclient на loadStudents_noCache
Если вы измените метод загрузки на loadStudents_noCache в конструкторе StudentComponent, выходные данные не будут кэшироваться в данных. Это показывает разницу между кэшированием и отсутствием кэширования.
this.loadStudents_noCache().then(data => { this.setState({ students:data.students, serverTime:data.getTime }) })
Из вышеприведенного вывода ясно, что если вы переключаетесь между вкладками, время с сервера GraphQL всегда будет самым последним, что означает, что данные не кэшируются.