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 utilitycreate-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.jssrc 폴더 및 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 서버의 시간이 항상 최신이므로 데이터가 캐시되지 않음을 알 수 있습니다.