GraphQL-캐싱
캐싱은 임시 저장 영역에 데이터를 저장하는 프로세스입니다. cache. 최근에 방문한 페이지로 돌아 가면 브라우저는 원래 서버가 아닌 캐시에서 해당 파일을 가져올 수 있습니다. 이렇게하면 추가 트래픽의 부담으로부터 시간과 네트워크를 절약 할 수 있습니다.
GraphQL과 상호 작용하는 클라이언트 응용 프로그램은 끝에서 데이터 캐싱을 담당합니다. 이에 대한 한 가지 가능한 패턴은 id와 같은 필드를 전역 적으로 고유 한 식별자로 예약하는 것입니다.
InMemory 캐시
InMemoryCache는 Redux와 같은 다른 라이브러리를 사용하지 않고 GraphQL 클라이언트 애플리케이션에서 일반적으로 사용되는 정규화 된 데이터 저장소입니다.
ApolloClient와 함께 InMemoryCache를 사용하는 샘플 코드는 다음과 같습니다.
import {ApolloClient, HttpLink, InMemoryCache} from 'apollo-boost'
const cache = new InMemoryCache();
const client = new ApolloClient({
link: new HttpLink(),
cache
});
InMemoryCache 생성자는 캐시를 사용자 지정하는 속성이있는 선택적 구성 개체를 사용합니다.
Sr. 아니. | 매개 변수 및 설명 |
---|---|
1 | addTypename __typename을 문서에 추가할지 여부를 결정하는 부울 (기본값 : true) |
2 | dataIdFromObject 데이터 객체를 취하고 저장소의 데이터를 정규화 할 때 사용할 고유 식별자를 반환하는 함수 |
삼 | fragmentMatcher 기본적으로 InMemoryCache는 휴리스틱 조각 매처를 사용합니다. |
4 | cacheRedirects 요청이 발생하기 전에 쿼리를 캐시의 다른 항목으로 리디렉션하는 함수 맵입니다. |
삽화
우리는 ReactJS에서 두 개의 탭이있는 단일 페이지 애플리케이션을 만들 것입니다. 하나는 홈 탭용이고 다른 하나는 학생용입니다. 학생 탭은 GraphQL 서버 API에서 데이터를로드합니다. 애플리케이션은 사용자가 홈 탭에서 학생 탭으로 이동할 때 학생 데이터 를 쿼리합니다 . 결과 데이터는 애플리케이션에 의해 캐시됩니다.
또한 다음을 사용하여 서버 시간을 쿼리합니다. getTime페이지가 캐시되었는지 확인하는 필드입니다. 캐시에서 데이터가 반환되면 페이지에 서버로 보낸 첫 번째 요청 시간이 표시됩니다. 데이터가 서버에 대한 새로운 요청의 결과 인 경우 항상 서버의 최신 시간을 표시합니다.
서버 설정
다음은 서버를 설정하는 단계입니다.
1 단계-프로젝트에 필요한 종속성 다운로드 및 설치
폴더 생성 cache-server-app. 디렉토리를 다음으로 변경하십시오. 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 utility 과 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 Client를 설치하려면 새 터미널을 열고 현재 프로젝트 폴더 경로에 있어야합니다. 다음 명령을 입력하십시오-
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
Students Component를 포함 할 추가 파일 students.js를 추가하십시오. 학생 세부 정보는 학생 구성 요소를 통해 가져옵니다. 앱 구성 요소에서는 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에서 구성 요소 학생 편집
Students Component에서 데이터를로드하기 위해 다음 두 가지 접근 방식을 사용합니다.
Fetch 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리소스를 가져 오기위한 간단한 인터페이스입니다. Fetch를 사용하면 이전 XMLHttpRequest보다 웹 요청을 만들고 응답을 처리하기가 더 쉽습니다. 다음 방법은 가져 오기 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 단계 -npm start로 React 애플리케이션 실행
홈 탭에서 학생 탭으로 전환하여 반응 애플리케이션을 테스트 할 수 있습니다. 학생 탭에 서버의 데이터가로드되면. 데이터를 캐시합니다. 집에서 학생 탭으로 여러 번 전환하여 테스트 할 수 있습니다. 출력은 다음과 같습니다.
URL을 입력하여 학생 페이지를 먼저로드 한 경우 http://localhost:3000/#/students, 반응 앱과 GraphQL의로드 시간이 거의 동일하다는 것을 알 수 있습니다. 그 후 홈 뷰로 전환하고 GraphQL 서버로 돌아 가면 시간이 변경되지 않습니다. 이것은 데이터가 캐시되었음을 보여줍니다.
7 단계-loadWithApolloclient 호출을 loadStudents_noCache로 변경
로드 방법을 다음으로 변경하면 loadStudents_noCacheStudentComponent 생성자에서 출력은 데이터를 캐시하지 않습니다. 이것은 캐싱과 비 캐싱의 차이를 보여줍니다.
this.loadStudents_noCache().then(data => {
this.setState({
students:data.students,
serverTime:data.getTime
})
})
위의 출력에서 탭 사이를 앞뒤로 전환하면 graphql 서버의 시간이 항상 최신이므로 데이터가 캐시되지 않음을 알 수 있습니다.