GraphQL-퀵 가이드

GraphQL은 RESTful API 호출을 최적화하기 위해 Facebook에서 개발 한 오픈 소스 서버 측 기술입니다. 실행 엔진이자 데이터 쿼리 언어입니다. 이 장에서는 GraphQL 사용의 이점에 대해 설명합니다.

왜 GraphQL인가

RESTful API는 명확하고 잘 구조화 된 리소스 지향 접근 방식을 따릅니다. 그러나 데이터가 더 복잡해지면 경로가 길어집니다. 때로는 단일 요청으로 데이터를 가져올 수 없습니다. 이것이 GraphQL이 유용한 곳입니다. GraphQL은 데이터를 탐색, 검색 및 수정하기위한 강력한 쿼리 구문을 사용하여 그래프 형태로 데이터를 구조화합니다.

다음은 GraphQL 쿼리 언어 사용의 장점입니다-

원하는 것을 요청하고 가져옵니다.

API에 GraphQL 쿼리를 보내고 필요한 것을 정확히 얻으십시오. GraphQL 쿼리는 항상 예측 가능한 결과를 반환합니다. GraphQL을 사용하는 애플리케이션은 빠르고 안정적입니다. Restful 서비스와 달리 이러한 애플리케이션은 서버에서 가져와야하는 데이터를 제한 할 수 있습니다.

다음 예제는 이것을 더 잘 이해하는 데 도움이 될 것입니다.

id, firstName, lastNamecollegeName 속성을 가진 비즈니스 오브젝트 Student 를 고려해 보겠습니다 . 모바일 애플리케이션이 firstNameid 만 가져와야한다고 가정하십시오 . / api / v1 / students 와 같은 REST 엔드 포인트를 설계 하면 학생 객체의 모든 필드에 대한 데이터를 가져옵니다 . 즉, RESTful 서비스가 데이터를 오버 페치합니다. 이 문제는 GraphQL을 사용하여 해결할 수 있습니다.

아래 주어진 GraphQL 쿼리를 고려하십시오-

{
   students {
      id
      firstName
   }
}

이것은 id 및 firstname 필드에 대한 값만 반환합니다. 쿼리는 학생 개체의 다른 속성에 대한 값을 가져 오지 않습니다. 위에 설명 된 쿼리의 응답은 다음과 같습니다.

{
   "data": {
      "students": [
         {
            "id": "S1001",
            "firstName": "Mohtashim"
         },
         {
            "id": "S1002",
            "firstName": "Kannan"
         }
      ]
   }
}

단일 요청으로 많은 리소스 가져 오기

GraphQL 쿼리는 관련 비즈니스 객체를 원활하게 검색하는 데 도움이되지만 일반적인 REST API는 여러 URL에서로드해야합니다. GraphQL API는 단일 요청으로 애플리케이션에 필요한 모든 데이터를 가져옵니다. GraphQL을 사용하는 애플리케이션은 느린 모바일 네트워크 연결에서도 빠를 수 있습니다.

이름과 위치라는 속성을 가진 하나의 비즈니스 객체 인 College 를 고려해 보겠습니다 . 학생 비즈니스 오브젝트는 대학 객체와의 연관 관계를 가지고있다. 학생과 대학의 세부 정보를 가져 오기 위해 REST API를 사용한다면 결국 서버에 / api / v1 / students/ api / v1 / colleges 와 같은 두 가지 요청을합니다 . 이로 인해 각 요청에서 데이터를 적게 가져옵니다. 따라서 모바일 애플리케이션은 원하는 데이터를 얻기 위해 서버를 여러 번 호출해야합니다.

그러나 모바일 애플리케이션은 GraphQL을 사용하여 단일 요청으로 Student 및 College 개체에 대한 세부 정보를 가져올 수 있습니다.

다음은 데이터를 가져 오는 GraphQL 쿼리입니다-

{
   students{
      id
      firstName
      lastName
      college{
         name
         location
      }
   }
}

위 쿼리의 출력은 아래와 같이 요청한 필드를 정확히 포함합니다.

{
   "data": {
      "students": [
         {
            "id": "S1001",
            "firstName": "Mohtashim",
            "lastName": "Mohammad",
            "college": {
               "name": "CUSAT",
               "location": "Kerala"
            }
         },
         
         {
            "id": "S1002",
            "firstName": "Kannan",
            "lastName": "Sudhakaran",
            "college": {
               "name": "AMU",
               "location": "Uttar Pradesh"
            }
         },
         
         {
            "id": "S1003",
            "firstName": "Kiran",
            "lastName": "Panigrahi",
            "college": {
               "name": "AMU",
               "location": "Uttar Pradesh"
            }
         }
      ]
   }
}

유형 시스템으로 가능한 것을 설명하십시오.

GraphQL은 강력한 형식이며 쿼리는 필드 및 관련 데이터 형식을 기반으로합니다. GraphQL 쿼리에 유형 불일치가있는 경우 서버 응용 프로그램은 명확하고 유용한 오류 메시지를 반환합니다. 이를 통해 클라이언트 응용 프로그램에서 원활한 디버깅과 버그를 쉽게 감지 할 수 있습니다. GraphQL은 또한 명시 적 데이터 변환 및 구문 분석을 줄이는 데 도움이되는 클라이언트 측 라이브러리를 제공합니다.

StudentCollege 데이터 유형 의 예 는 다음과 같습니다.

type Query {
   students:[Student]
}

type Student {
   id:ID!
   firstName:String
   lastName:String
   fullName:String
   college:College
}

type College {
   id:ID!
   name:String
   location:String
   rating:Float
   students:[Student]
}

강력한 개발자 도구로 더 빠르게 이동

GraphQL은 문서화 및 쿼리 테스트를위한 풍부한 개발자 도구를 제공합니다. GraphiQL은 쿼리와 스키마에 대한 문서를 생성하는 훌륭한 도구입니다. 또한 쿼리를 작성하는 동안 GraphQL API 및 지능형 코드 완성 기능을 테스트 할 수있는 쿼리 편집기를 제공합니다.

이 장에서는 GraphQL의 환경 설정에 대해 알아 봅니다. 이 튜토리얼의 예제를 실행하려면 다음이 필요합니다.

  • Linux, macOS 또는 Windows를 실행하는 컴퓨터.

  • 웹 브라우저, 가급적 최신 버전의 Google 크롬.

  • 최신 버전의 Node.js가 설치되었습니다. 최신 LTS 버전을 권장합니다.

  • VSCode 용 확장 GraphQL이 설치된 Visual Studio Code 또는 원하는 코드 편집기.

Nodejs로 GraphQL 서버를 구축하는 방법

아래 그림과 같이 Nodejs를 사용하여 GraphQL 서버를 구축하는 자세한 단계별 접근 방식을 살펴 보겠습니다.

1 단계-노드 및 Npm 버전 확인

NodeJs를 설치 한 후 터미널에서 다음 명령을 사용하여 node 및 npm의 버전을 확인하십시오.

C:\Users\Admin>node -v
v8.11.3

C:\Users\Admin>npm -v
5.6.0

2 단계-프로젝트 폴더 생성 및 VSCode에서 열기

프로젝트의 루트 폴더는 test-app으로 이름을 지정할 수 있습니다.

아래 지침을 사용하여 Visual Studio 코드 편집기를 사용하여 폴더를 엽니 다.

C:\Users\Admin>mkdir test-app
C:\Users\Admin>cd test-app
C:\Users\Admin\test-app>code.

3 단계-package.json 생성 및 종속성 설치

GraphQL 서버 애플리케이션의 모든 종속성을 포함 할 package.json 파일을 만듭니다.

{
   "name": "hello-world-server",
   "private": true,
   "scripts": {
      "start": "nodemon --ignore data/ server.js"
   },
   
   "dependencies": {
      "apollo-server-express": "^1.4.0",
      "body-parser": "^1.18.3",
      "cors": "^2.8.4",
      "express": "^4.16.3",
      "graphql": "^0.13.2",
      "graphql-tools": "^3.1.1"
   },
   
   "devDependencies": {
      "nodemon": "1.17.1"
   }
}

아래 주어진 명령을 사용하여 종속성을 설치하십시오-

C:\Users\Admin\test-app>npm install

4 단계-데이터 폴더에 플랫 파일 데이터베이스 생성

이 단계에서는 플랫 파일을 사용하여 데이터를 저장하고 검색합니다. 폴더 데이터를 만들고 두 개의 파일을 추가합니다.students.jsoncolleges.json.

다음은 colleges.json 파일-

[
   {
      "id": "col-101",
      "name": "AMU",
      "location": "Uttar Pradesh",
      "rating":5.0
   },
   
   {
      "id": "col-102",
      "name": "CUSAT",
      "location": "Kerala",
      "rating":4.5
   }
]

다음은 students.json 파일-

[
   {
      "id": "S1001",
      "firstName":"Mohtashim",
      "lastName":"Mohammad",
      "email": "[email protected]",
      "password": "pass123",
      "collegeId": "col-102"
   },
   
   {
      "id": "S1002",
      "email": "[email protected]",
      "firstName":"Kannan",
      "lastName":"Sudhakaran",
      "password": "pass123",
      "collegeId": "col-101"
   },
   
   {
      "id": "S1003",
      "email": "[email protected]",
      "firstName":"Kiran",
      "lastName":"Panigrahi",
      "password": "pass123",
      "collegeId": "col-101"
   }
]

5 단계-데이터 액세스 계층 생성

데이터 폴더 내용을로드하는 데이터 저장소를 만들어야합니다. 이 경우 수집 변수, 학생대학이 필요 합니다. 응용 프로그램에 데이터가 필요할 때마다 이러한 컬렉션 변수를 사용합니다.

다음과 같이 프로젝트 폴더에 db.js 파일을 만듭니다.

const { DataStore } = require('notarealdb');

const store = new DataStore('./data');

module.exports = {
   students:store.collection('students'),
   colleges:store.collection('colleges')
};

6 단계-스키마 파일 schema.graphql 생성

현재 프로젝트 폴더에 스키마 파일을 생성하고 다음 내용을 추가합니다.

type Query  {
   test: String
}

7 단계-Resolver 파일, resolvers.js 생성

현재 프로젝트 폴더에 리졸버 파일을 생성하고 다음 내용을 추가합니다.

const Query = {
   test: () => 'Test Success, GraphQL server is up & running !!'
}
module.exports = {Query}

8 단계-Server.js 생성 및 GraphQL 구성

서버 파일을 생성하고 다음과 같이 GraphQL을 구성합니다.

const bodyParser = require('body-parser');
const cors = require('cors');
const express = require('express');
const db = require('./db');

const port = process.env.PORT || 9000;
const app = express();

const fs = require('fs')
const typeDefs = fs.readFileSync('./schema.graphql',{encoding:'utf-8'})
const resolvers = require('./resolvers')

const {makeExecutableSchema} = require('graphql-tools')
const schema = makeExecutableSchema({typeDefs, resolvers})

app.use(cors(), bodyParser.json());

const  {graphiqlExpress,graphqlExpress} = require('apollo-server-express')
app.use('/graphql',graphqlExpress({schema}))
app.use('/graphiql',graphiqlExpress({endpointURL:'/graphql'}))

app.listen(
   port, () => console.info(
      `Server started on port ${port}`
   )
);

9 단계-애플리케이션 실행 및 GraphiQL로 테스트

다음과 같이 프로젝트 test-app의 폴더 구조를 확인하십시오.

test-app /
   -->package.json
   -->db.js
   -->data
      students.json
      colleges.json
   -->resolvers.js
   -->schema.graphql
   -->server.js

다음과 같이 npm start 명령을 실행하십시오-

C:\Users\Admin\test-app>npm start

서버는 9000 포트에서 실행되므로 GraphiQL 도구를 사용하여 애플리케이션을 테스트 할 수 있습니다. 브라우저를 열고 URL http : // localhost : 9000 / graphiql을 입력합니다. 편집기에 다음 쿼리를 입력하십시오-

{
   Test 
}

서버의 응답은 다음과 같습니다.

{
   "data": {
      "test": "Test Success, GraphQL server is running !!"
   }
}

GraphQL은 GraphQL 서버의 동작을 설명하는 사양입니다. 지원되는 프로토콜, 서버에서 수락 할 수있는 데이터 형식, 서버에서 반환하는 응답 형식 등과 같이 요청 및 응답을 처리하는 방법에 대한 일련의 지침입니다. 클라이언트가 GraphQL에 보내는 요청 서버를 쿼리라고합니다. GraphQL의 또 다른 중요한 개념은 전송 계층 불가지론입니다. TCP, websocket 또는 기타 전송 계층 프로토콜과 같은 사용 가능한 네트워크 프로토콜과 함께 사용할 수 있습니다. 또한 데이터베이스에 중립적이므로 관계형 또는 NoSQL 데이터베이스와 함께 사용할 수 있습니다.

GraphQL Server는 아래 나열된 세 가지 방법 중 하나를 사용하여 배포 할 수 있습니다.

  • 연결된 데이터베이스가있는 GraphQL 서버
  • 기존 시스템을 통합하는 GraphQL 서버
  • 하이브리드 접근

연결된 데이터베이스가있는 GraphQL 서버

이 아키텍처에는 통합 데이터베이스가있는 GraphQL 서버가 있으며 종종 새 프로젝트와 함께 사용할 수 있습니다. 쿼리를 받으면 서버는 요청 페이로드를 읽고 데이터베이스에서 데이터를 가져옵니다. 이를 쿼리 해결이라고합니다. 클라이언트에 반환 된 응답은 공식 GraphQL 사양에 지정된 형식을 따릅니다.

위의 다이어그램에서 GraphQL 서버와 데이터베이스는 단일 노드에 통합되어 있습니다. 클라이언트 (데스크톱 / 모바일)는 HTTP를 통해 GraphQL 서버와 통신합니다. 서버는 요청을 처리하고 데이터베이스에서 데이터를 가져와 클라이언트에 반환합니다.

기존 시스템을 통합하는 GraphQL 서버

이 접근 방식은 레거시 인프라와 다양한 API가있는 회사에 유용합니다. GraphQL은 기존 시스템에서 마이크로 서비스, 레거시 인프라 및 타사 API를 통합하는 데 사용할 수 있습니다.

위의 다이어그램에서 GraphQL API는 클라이언트와 기존 시스템 간의 인터페이스 역할을합니다. 클라이언트 애플리케이션은 GraphQL 서버와 통신하여 쿼리를 해결합니다.

하이브리드 접근

마지막으로 위의 두 가지 접근 방식을 결합하여 GraphQL 서버를 구축 할 수 있습니다. 이 아키텍처에서 GraphQL 서버는 수신 된 모든 요청을 해결합니다. 연결된 데이터베이스 또는 통합 API에서 데이터를 검색합니다. 이것은 아래 그림에 나와 있습니다.

이 장에서는 다양한 GraphQL 구성 요소와 서로 통신하는 방식에 대해 설명합니다. 전체 애플리케이션 구성 요소는 다음과 같이 구분할 수 있습니다.

  • 서버 측 구성 요소
  • 클라이언트 측 구성 요소

서버 측 구성 요소

GraphQL 서버는 서버 측의 핵심 구성 요소를 형성하고 GraphQL 클라이언트 응용 프로그램에서 오는 쿼리를 구문 분석 할 수 있습니다. Apollo Server는 GraphQL 사양의 가장 일반적으로 사용되는 구현입니다. 다른 서버 프로그래밍 구성 요소는 다음과 같습니다.

Sr. 아니. Server Essentials 및 설명
1

Schema

GraphQL 스키마는 GraphQL 서버 구현의 중심에 있으며 연결하는 클라이언트가 사용할 수있는 기능을 설명합니다.

2

Query

GraphQL 쿼리는 데이터베이스 또는 레거시 API에서 데이터를 검색하기위한 클라이언트 애플리케이션 요청입니다.

Resolver

해석기는 GraphQL 연산을 데이터로 변환하기위한 지침을 제공합니다. 리졸버 함수를 정의하여 쿼리를 데이터로 해결합니다.

클라이언트 측 구성 요소

다음은 클라이언트 측 구성 요소입니다.

Sr. 아니. 도구 및 설명
1

GraphiQL

GraphQL 쿼리 및 변형을 편집하고 테스트하기위한 브라우저 기반 인터페이스입니다.

2

ApolloClient

GraphQL 클라이언트 애플리케이션을 구축하는 최고의 도구입니다. 모든 자바 스크립트 프런트 엔드와 잘 통합됩니다.

아래 다이어그램은 Client-Server architecture. 웹 서버는 NodeJ 및 Express 프레임 워크를 기반으로합니다. ReactJS 애플리케이션 (Apollo Client 라이브러리를 사용하여 구축) 또는 GraphiQL 브라우저 애플리케이션에 의해 Apollo GraphQL Server에 요청이 이루어집니다. 쿼리는 서버에 정의 된 스키마에 대해 구문 분석되고 유효성이 검사됩니다. 요청 스키마가 유효성 검사를 통과하면 연결된 확인자 함수가 실행됩니다. 리졸버에는 API 또는 데이터베이스에서 데이터를 가져 오는 코드가 포함됩니다.

이 장에서는 인사 메시지 HelloWorld를 반환하고 GraphiQL을 사용하여 액세스하는 간단한 API를 생성합니다.

이 예제는 NodeJS, Express 및 Apollo 서버를 기반으로합니다. 우리는 다음 단계를 통해 모든 개념을 결합하는 방법을 배웁니다.

1 단계-Express 설정

ExpressJS는 웹 사이트와 웹 애플리케이션을 구축하는 데 도움이되는 웹 애플리케이션 프레임 워크입니다. 이 예에서는 Express 프레임 워크 위에 GraphQL API를 빌드합니다.

다음 단계는 폴더를 만드는 것입니다. hello-world-server터미널에서 동일한 폴더로 이동합니다. package.json을 추가하고 패키지에 이름을 지정하십시오. 이 패키지는 내부적으로 만 사용되므로 비공개로 선언 할 수 있습니다.

{
   "name":"hello-world-server",
   "private":true
}

아래와 같이 Express 서버에 대한 종속성을 설치하십시오-

C:\Users\Admin\hello-world-server>npm install express body-parser cors

body-parser 는 Express가 HTTP Post 요청을 효율적으로 처리하도록 도와주는 미들웨어 패키지입니다. cors 는 교차 출처 리소스 공유를 처리하는 또 다른 미들웨어 패키지입니다.

만들기 server.js 프로젝트 폴더에 파일을 넣고 다음을 입력하십시오-

const bodyParser = require('body-parser')
   const cors = require('cors')
   const express = require('express')
   const port = process.env.PORT|| 9000
   const app = express()
   
   //register middleware
   app.use(bodyParser.json() , cors())
   app.listen(port, () =>  console.log(`server is up and running at ${port}`)

Express 서버가 실행 중인지 확인하려면 터미널 창에서 다음 코드를 실행하십시오.

C:\Users\Admin\hello-world-server>node server.js

다음 출력이 서버 콘솔에 표시됩니다. 이는 익스프레스 서버가 포트 9000에서 실행 중임을 나타냅니다.

server is up and running at 9000

브라우저를 열고 다음을 입력하면 http://localhost:9000, 다음 화면이 표시됩니다-

서버를 중지하려면 Ctrl + C.

2 단계-GraphQL 및 Apollo 서버 설치

이제 Express가 구성되었으므로 다음 단계는 다음 GraphQL 종속성을 다운로드하는 것입니다.

  • graphql
  • graphql-tools
  • apollo-server-express@1

안정적인 릴리스이므로 Apollo 서버 v1.0을 사용할 것입니다. 이러한 종속성을 설치하려면 다음 명령을 입력하십시오-

C:\Users\Admin\hello-world-server>npm install graphql graphql-tools apollo-server-express@1

이러한 종속성이 성공적으로 설치되었는지 확인할 수 있습니다. package.json 이전에 만든 파일입니다.

{
   "name": "hello-world-server",
   "private": true,
   
   "dependencies": {
      "apollo-server-express": "^1.4.0",
      "body-parser": "^1.18.3",
      "cors": "^2.8.4",
      "express": "^4.16.3",
      "graphql": "^0.13.2",
      "graphql-tools": "^3.1.1"
   }
}

3 단계-스키마 정의

GraphQL 스키마는 서비스에서 가져올 수있는 개체의 종류와 포함 된 필드를 정의합니다. 스키마는 다음을 사용하여 정의 할 수 있습니다.GraphQL Schema Definition Language. 이제 다음 코드 스 니펫을server.js 파일-

// Adding Type Definitions
const typeDefinition = `
   type Query  {
      greeting: String
   }

여기서 쿼리에는 문자열 값 을 반환하는 인사말 속성이 포함되어 있습니다 .

4 단계-리졸버 생성

리졸버를 만드는 첫 번째 단계는 인사말 필드에 대한 요청을 처리하는 코드를 추가하는 것입니다. 이것은resolver. 해석기 함수의 구조는 스키마와 일치해야합니다. 다음 코드 조각을server.js 파일.

// Adding resolver
const  resolverObject = {
   Query : {
      greeting: () => 'Hello GraphQL  From TutorialsPoint !!'
   }
}

두 번째 단계는 다음을 사용하여 스키마와 리졸버를 바인딩하는 것입니다. makeExecutableSchema. 이 함수는 graphql-tools 모듈에 미리 정의되어 있습니다. 다음 코드 조각을 server.js 파일.

const {makeExecutableSchema} = require('graphql-tools')
const schema = makeExecutableSchema({typeDefs:typeDefinition, resolvers:resolverObject})

5 단계-ReactJS / GraphiQL 애플리케이션에서 데이터를 가져 오는 경로 정의

다음 코드 조각을 server.js 파일-

const {graphqlExpress, graphiqlExpress} = require('apollo-server-express')

   //create routes for graphql and graphiql
   app.use('/graphql',graphqlExpress({schema}))
   
   app.use('/graphiql',graphiqlExpress({endpointURL:'/graphql'}))

graphqlExpress의 기능은 경로를 등록하는 데 도움이http://localhost:9000/graphql. ReactJS 애플리케이션은이 끝점을 사용하여 데이터를 쿼리 할 수 ​​있습니다. 마찬가지로 graphqliExpress 함수는 경로를 등록하는 데 도움이됩니다.http://localhost:9000/graphiql. 이는 GraphiQL 브라우저 클라이언트에서 API를 테스트하는 데 사용됩니다.

완전한 server.js 코드는 다음과 같습니다.

const bodyParser = require('body-parser')
const cors = require('cors')
const express = require('express')
const port = process.env.PORT||9000
const app = express()

app.use(bodyParser.json() , cors())
const typeDefinition = `
type Query  {
   greeting: String
}`
const  resolverObject = {
   Query : {
      greeting: () => 'Hello GraphQL  From TutorialsPoint !!'
   }
}
const {makeExecutableSchema} = require('graphql-tools')

const schema = makeExecutableSchema({typeDefs:typeDefinition, resolvers:resolverObject})

const {graphqlExpress,graphiqlExpress} = require('apollo-server-express')

app.use('/graphql',graphqlExpress({schema}))
app.use('/graphiql',graphiqlExpress({endpointURL:'/graphql'}))
app.listen(port, () =>  console.log(`server is up and running ${port}`))

6 단계-애플리케이션 시작

실행 server.js 다음과 같이 Node.js 사용-

C:\Users\Admin\hello-world-server>node server.js

7 단계-GraphQL API 테스트

브라우저를 열고 입력하십시오. http://localhost:9000/graphiql. GraphiQL의 쿼리 탭에서 다음을 입력하십시오.

{
   greeting
}

서버의 응답은 다음과 같습니다.

{
   "data": {
      "greeting": "Hello GraphQL From TutorialsPoint !!"
   }
}

다음 이미지는 응답을 보여줍니다-

Note − Apollo Server 버전 1.0을 사용하고 있는지 확인하십시오.

GraphQL은 강력한 형식의 언어입니다. 유형 시스템은 GraphQL 애플리케이션에서 사용할 수있는 다양한 데이터 유형을 정의합니다. 유형 시스템은 클라이언트와 서버 간의 계약 인 스키마를 정의하는 데 도움이됩니다. 일반적으로 사용되는 GraphQL 데이터 유형은 다음과 같습니다.

Sr. 아니. 유형 및 설명
1

Scalar

단일 값 저장

2

Object

가져올 수있는 개체의 종류를 표시합니다.

Query

다른 특정 유형에 대한 진입 점 유형

4

Mutation

데이터 조작을위한 진입 점

5

Enum

사용자가 규정 된 옵션 목록에서 선택해야하는 상황에서 유용합니다.

스칼라 유형

스칼라 유형은 단일 값만 저장할 수있는 기본 데이터 유형입니다. GraphQL이 제공하는 기본 스칼라 유형은 다음과 같습니다.

  • Int − 부호있는 32 비트 정수

  • Float − 부호있는 배정 밀도 부동 소수점 값

  • String − UTF-8 자 시퀀스

  • Boolean − 참 또는 거짓

  • ID − 개체를 가져 오기위한 고유 식별자 또는 캐시의 키로 자주 사용되는 고유 식별자.

스칼라 유형을 정의하는 구문은 다음과 같습니다.

field: data_type

아래에 주어진 스 니펫은 문자열 값을 반환하는 greeting이라는 필드를 정의합니다.

greeting: String

개체 유형

개체 유형은 스키마에서 사용되는 가장 일반적인 유형이며 필드 그룹을 나타냅니다. 개체 유형 내의 각 필드는 다른 유형에 매핑되므로 중첩 된 유형이 허용됩니다. 즉, 객체 유형은 여러 스칼라 유형 또는 객체 유형으로 구성됩니다.

객체 유형을 정의하는 구문은 다음과 같습니다.

type object_type_name
{
   field1: data_type
   field2:data_type 
   ....
   fieldn:data_type
}

다음 코드 조각을 고려할 수 있습니다-

--Define an object type--

type Student {
   stud_id:ID
   firstname: String
   age: Int
   score:Float
}

--Defining a GraphQL schema--  

type Query
{
   stud_details:[Student]
}

위에 주어진 예는 객체 데이터 유형 Student를 정의합니다. 루트 쿼리 스키마 의 stud_details 필드는 Student 개체 목록을 반환합니다.

쿼리 유형

GraphQL 쿼리는 데이터를 가져 오는 데 사용됩니다. REST 기반 API에서 리소스를 요청하는 것과 같습니다. 간단하게하기 위해 쿼리 유형은 클라이언트 애플리케이션에서 GraphQL 서버로 전송 된 요청입니다. GraphQL은Schema Definition Language (SDL)쿼리를 정의합니다. 쿼리 유형은 GraphQL의 많은 루트 수준 유형 중 하나입니다.

쿼리를 정의하는 구문은 다음과 같습니다.

type Query {
   field1: data_type
   field2:data_type
   field2(param1:data_type,param2:data_type,...paramN:data_type):data_type
}

쿼리 정의의 예-

type Query  {
   greeting: String
}

돌연변이 유형

돌연변이는 서버로 전송되는 작업입니다. create, update 또는 delete데이터. REST 기반 API를 호출하는 PUT, POST, PATCH 및 DELETE 동사와 유사합니다.

Mutation은 GraphQL의 루트 수준 데이터 유형 중 하나입니다. Query 유형은 데이터 가져 오기 작업의 진입 점을 정의하는 반면 Mutation 유형은 데이터 조작 작업의 진입 점을 지정합니다.

Mutation 유형을 정의하는 구문은 다음과 같습니다.

type Mutation {
   field1: data_type
   field2(param1:data_type,param2:data_type,...paramN:data_type):data_type 
}

예를 들어, 다음과 같이 새 Student를 추가하기 위해 변형 유형을 정의 할 수 있습니다.

type Mutation {
   addStudent(firstName: String, lastName: String): Student
}

열거 형

Enum은 스칼라 유형과 유사합니다. 열거 형은 필드 값이 미리 지정된 옵션 목록의 값이어야하는 상황에서 유용합니다.

Enum 유형을 정의하는 구문은 다음과 같습니다.

type enum_name{
   value1
   value2
}

다음 스 니펫은 열거 형 유형을 정의하는 방법을 보여줍니다-

type Days_of_Week{
   SUNDAY
   MONDAY
   TUESDAY
   WEDNESDAY
   THURSDAY
   FRIDAY
   SATURDAY
}

목록 유형

목록은 특정 유형의 값 배열을 나타내는 데 사용할 수 있습니다. 목록은 객체 유형, 스칼라 및 열거 형을 래핑하는 유형 수정 자 []로 정의됩니다.

다음 구문은 목록 유형을 정의하는 데 사용할 수 있습니다-

field:[data_type]

아래 예제는 목록 유형 할일을 정의합니다-

type Query {
   todos: [String]
}

nullable이 아닌 유형

기본적으로 각 코어 스칼라 유형은 널로 설정할 수 있습니다. 즉, 이러한 유형은 지정된 유형의 값을 반환하거나 값이 없을 수 있습니다. 이 기본값을 재정의하고 필드를 정의해야 함을 지정하려면 느낌표 (!)를 형식에 추가 할 수 있습니다. 이렇게하면 쿼리에서 반환 된 결과에 값이 있는지 확인할 수 있습니다.

다음 구문은 nullable이 아닌 필드를 정의하는 데 사용할 수 있습니다-

field:data_type!

아래 예에서 stud_id 는 필수 필드로 선언됩니다.

type Student {
   stud_id:ID!
   firstName:String
   lastName:String
   fullName:String
   college:College
}

GraphQL 스키마는 GraphQL 서버 구현의 핵심입니다. 연결하는 클라이언트 응용 프로그램에서 사용할 수있는 기능에 대해 설명합니다. 모든 프로그래밍 언어를 사용하여 GraphQL 스키마를 생성하고 그 주위에 인터페이스를 구축 할 수 있습니다.

GraphQL 런타임은 나타내는 데이터 서비스의 기능을 게시하기 위해 일반적인 그래프 기반 스키마를 정의합니다. 클라이언트 응용 프로그램은 기능 내에서 스키마를 쿼리 할 수 ​​있습니다. 이 접근 방식은 클라이언트를 서버에서 분리하고 독립적으로 발전하고 확장 할 수 있도록합니다.

이 장에서는 Apollo 서버를 사용하여 GraphQL 쿼리를 실행합니다. 그만큼makeExecutableSchema graphql-tools의 함수는 스키마와 리졸버를 바인딩하는 데 도움이됩니다.

makeExecutableSchema 함수 구문

그만큼 makeExecutableSchema함수는 개체 유형의 단일 인수 {}를 사용합니다. 이 함수를 사용하는 구문은 다음과 같습니다.

import { makeExecutableSchema } from 'graphql-tools';

const jsSchema = makeExecutableSchema({
   typeDefs,
   resolvers, // optional
   logger, // optional
   allowUndefinedInResolve = false, // optional
   resolverValidationOptions = {}, // optional
   directiveResolvers = null, // optional
   schemaDirectives = null,  // optional
   parseOptions = {},  // optional
   inheritResolversFromInterfaces = false  // optional
});

Sr. 아니. 매개 변수 및 설명
1

typeDefs

이것은 필수 인수입니다. GraphQL 쿼리를 UTF-8 문자열로 나타냅니다.

2

Resolvers

이것은 선택적 인수입니다 (기본적으로 빈 개체). 여기에는 쿼리를 처리하는 기능이 있습니다.

logger

이것은 선택적 인수이며 서버 콘솔에 오류를 인쇄하는 데 사용할 수 있습니다.

4

parseOptions

이것은 선택적 인수이며 typeDefs를 문자열로 지정할 때 구문 분석을 사용자 정의 할 수 있습니다.

5

allowUndefinedInResolve

이것은 기본적으로 true입니다. false로 설정하면 해석 함수가 undefined를 반환하는 경우 오류가 발생합니다.

6

resolverValidationOptions

선택적 인수이며 부울 속성이있는 개체를받습니다.

7

inheritResolversFromInterfaces

이것은 선택적 인수이며 리졸버 개체 상속을 확인하기 위해 부울 인수를 허용합니다.

삽화

이 스키마를 이해하는 간단한 응용 프로그램을 만들어 보겠습니다. 이렇게하면 서버에서 학생 목록을 쿼리하기위한 스키마가 생성됩니다. 학생 데이터는 플랫 파일에 저장되며 다음과 같은 노드 모듈을 사용합니다.notarealdb 데이터베이스를 위조하고 플랫 파일에서 읽습니다.

1 단계-프로젝트에 필요한 종속성 다운로드 및 설치

다음과 같은 폴더를 만듭니다. schema-app. 터미널에서 디렉토리를 schema-app으로 변경하십시오. 그런 다음 환경 설정 장에 설명 된 3 ~ 5 단계에 따라 다운로드 및 설치 프로세스를 완료합니다.

2 단계-스키마 생성

더하다 schema.graphql 프로젝트 폴더의 파일, schema-app 다음 코드를 추가하십시오-

type Query {
   greeting:String
   students:[Student]
}

type Student {
   id:ID!
   firstName:String
   lastName:String
   password:String
   collegeId:String
}

스키마의 루트는 쿼리 유형입니다. 쿼리에는 각각 String과 학생 목록을 반환하는 greeting과 Students라는 두 개의 필드가 있습니다. Student는 여러 필드를 포함하므로 Object 유형으로 선언됩니다. ID 필드는 nullable이 아닌 것으로 선언됩니다.

3 단계-Resolver 생성

파일 생성 resolvers.js 프로젝트 폴더에 다음 코드를 추가하십시오-

const db = require('./db')
const Query = {
   greeting:() => {
      return "hello from  TutorialsPoint !!!"
   },
   students:() => db.students.list()
}

module.exports = {Query}

여기서 인사와 학생은 쿼리를 처리하는 해결 자입니다. students resolver function데이터 액세스 레이어에서 학생 목록을 반환합니다. 모듈 외부에서 해석기 기능에 액세스하려면 Query 객체를 다음을 사용하여 내 보내야합니다.module.exports.

4 단계-애플리케이션 실행

server.js 파일을 만들고 환경 설정 장의 8 단계를 참조하십시오. 다음 단계는 터미널에서 npm start 명령을 실행하는 것입니다. 서버는 9000 포트에서 실행됩니다. 여기서는 GraphiQL을 클라이언트로 사용하여 애플리케이션을 테스트합니다. 브라우저를 열고 URL을 입력하십시오.http://localhost:9000/graphiql.

편집기에 다음 쿼리를 입력하십시오-

{
   greeting
   students {
      id
      firstName
      lastName
   }
}

쿼리는 아래와 같이 출력을 표시합니다.

Note− students.json을 RESTful API 호출로 대체하여 학생 데이터 또는 MySQL 또는 MongoDB와 같은 실제 데이터베이스를 검색 할 수 있습니다. GraphQL은 성능을 향상시키기 위해 원래 애플리케이션 계층을 둘러싼 얇은 래퍼가됩니다.

Resolver는 GraphQL 쿼리에 대한 응답을 생성하는 함수 모음입니다. 간단히 말해서 리졸버는 GraphQL 쿼리 처리기 역할을합니다. GraphQL 스키마의 모든 리졸버 함수는 아래와 같이 4 개의 위치 인수를받습니다.

fieldName:(root, args, context, info) => { result }

리졸버 기능의 예는 다음과 같습니다.

//resolver function  with no parameters and returning string
greeting:() => {
   return "hello from  TutorialsPoint !!!"
}

//resolver function with no parameters and returning list
students:() => db.students.list()

//resolver function with arguments and returning object
studentById:(root,args,context,info) => {
   return db.students.get(args.id);
}

다음은 위치 인수와 설명입니다.

Sr. 아니. 인수 및 설명
1

root

부모 필드의 해석기에서 반환 된 결과를 포함하는 개체입니다.

2

args

쿼리의 필드에 전달 된 인수가있는 개체입니다.

context

이것은 특정 쿼리의 모든 해석기가 공유하는 객체입니다.

4

info

여기에는 필드 이름, 루트의 필드 경로 등 쿼리 실행 상태에 대한 정보가 포함됩니다.

확인자 결과 형식

GraphQL의 해석기는 아래와 같이 다양한 유형의 값을 반환 할 수 있습니다.

Sr. 아니. 인수 및 설명
1

null or undefined

이것은 개체를 찾을 수 없음을 나타냅니다.

2

array

스키마가 필드의 결과가 목록이어야 함을 나타내는 경우에만 유효합니다.

promise

리졸버는 종종 데이터베이스 또는 백엔드 API에서 가져 오기와 같은 비동기 작업을 수행하므로 프라 미스를 반환 할 수 있습니다.

4

scalar or object

리졸버는 다른 값을 반환 할 수도 있습니다.

삽화

리졸버를 이해하기위한 간단한 애플리케이션을 만들어 보겠습니다. 이것은 서버에서 ID로 학생을 쿼리하기위한 스키마를 생성합니다. 학생 데이터는 플랫 파일에 저장되며 다음과 같은 노드 모듈을 사용합니다.notarealdb 데이터베이스를 위조하고 플랫 파일에서 읽습니다.

다음은 간단한 응용 프로그램을 만드는 단계별 프로세스입니다.

1 단계-프로젝트에 필요한 종속성 다운로드 및 설치

다음과 같은 폴더를 만듭니다. resolver-app. 디렉토리를 다음으로 변경하십시오.resolver-app터미널에서. 나중에 환경 설정 장의 3 ~ 5 단계를 따릅니다.

2 단계-스키마 생성

프로젝트 폴더 resolver-app에 schema.graphql 파일을 추가하고 다음 코드를 추가합니다.

type Query { 
   greeting:String
   students:[Student]
   studentById(id:ID!):Student 
}

type Student {
   id:ID!
   firstName:String
   lastName:String
   password:String
   collegeId:String
}

스키마 파일은 사용자가 greeting, studentsstudentById에 대해 쿼리 할 수 ​​있음을 보여줍니다 . 특정 ID를 가진 학생을 검색하려면data type ID!nullable이 아닌 고유 식별자 필드를 표시합니다. 학생들의 필드는 학생들의 배열을 반환하고, 인사 반환에게 간단한 문자열 값을.

3 단계-Resolver 생성

파일 생성 resolvers.js 프로젝트 폴더에 다음 코드를 추가하십시오-

const db = require('./db')
const Query = {
   //resolver function for greeting
   greeting:() => {
      return "hello from  TutorialsPoint !!!"
   },
   
   //resolver function for students returns list
   students:() => db.students.list(),

   //resolver function for studentbyId
   studentById:(root,args,context,info) => {
      //args will contain parameter passed in query
      return db.students.get(args.id);
   }
}
module.exports = {Query}

여기서 studentById 는 세 가지 매개 변수를받습니다. 이 장에서 설명했듯이 studentId 는 args에서 검색 할 수 있습니다. root에는 Query 개체 자체가 포함됩니다. 특정 학생을 반환하려면 students 컬렉션에서 id 매개 변수를 사용하여 get 메서드를 호출해야합니다.

여기서 인사말, students, studentById 는 쿼리를 처리하는 해결 자입니다.students resolver function데이터 액세스 레이어에서 학생 목록을 반환합니다. 모듈 외부에서 리졸버 기능에 액세스하려면 module.exports를 사용하여 Query 객체를 내 보내야합니다.

4 단계-애플리케이션 실행

server.js 파일을 만듭니다. 환경 설정 장의 8 단계를 참조하십시오. 터미널에서 npm start 명령을 실행합니다. 서버는 9000 포트에서 실행됩니다. 여기서는 GraphiQL을 클라이언트로 사용하여 애플리케이션을 테스트합니다.

브라우저를 열고 URL을 입력하십시오. http://localhost:9000/graphiql. 편집기에 다음 쿼리를 입력하십시오-

{  
   studentById(id:"S1001") {
      id
      firstName
      lastName
   }
}

위 쿼리의 출력은 다음과 같습니다.

{
   "data": {
      "studentById": {
         "id": "S1001",
         "firstName": "Mohtashim",
         "lastName": "Mohammad"
      }
   }
}

GraphQL 작업은 읽기 또는 쓰기 작업 일 수 있습니다. GraphQL 쿼리는 값을 읽거나 가져 오는 데 사용되는 반면 변형은 값을 쓰거나 게시하는 데 사용됩니다. 두 경우 모두 작업은 GraphQL 서버가 특정 형식의 데이터를 구문 분석하고 응답 할 수있는 간단한 문자열입니다. 일반적으로 모바일 및 웹 애플리케이션에 사용되는 인기있는 응답 형식은 JSON입니다.

쿼리를 정의하는 구문은 다음과 같습니다.

//syntax 1
query query_name{ someField }

//syntax 2
{ someField }

다음은 쿼리의 예입니다-

//query with name myQuery
query myQuery{
   greeting
}

// query without any name
{
   greeting
}

위의 예에서 쿼리 키워드가 선택 사항이라는 것이 분명합니다.

GraphQL 쿼리는 데이터 오버 페칭을 줄이는 데 도움이됩니다. Restful API와 달리 GraphQL을 사용하면 사용자가 서버에서 가져와야하는 필드를 제한 할 수 있습니다. 이는 네트워크를 통한 더 적은 쿼리와 더 적은 트래픽을 의미합니다. 결과적으로 응답 시간이 줄어 듭니다.

그림 1-사용자 지정 필드를 사용하여 학생 모델 쿼리

이 예에서는 json 파일에 저장된 학생 세트가 있습니다. 각 학생 모델에는 firstName, lastName 및 id와 같은 필드가 있지만 fullName은 없습니다. 여기에서는 모든 학생의 fullName을 검색하는 쿼리를 만드는 방법에 대해 설명합니다. 이를 위해 두 스키마 해석기에서 fullName 필드를 만들어야합니다.

아래 단계를 사용하여이 그림을 수행하는 방법을 살펴 보겠습니다.

1 단계-프로젝트에 필요한 종속성 다운로드 및 설치

다음과 같은 폴더를 만듭니다. query-app. 디렉토리를 다음으로 변경하십시오.query-app터미널에서. 나중에 환경 설정 장에 설명 된 3 ~ 5 단계를 따릅니다.

2 단계-스키마 생성

더하다 schema.graphql 프로젝트 폴더 query-app에 파일을 추가하고 다음 코드를 추가하십시오.

type Query {
   greeting:String
   students:[Student]
   studentById(id:ID!):Student
}

type Student {
   id:ID!
   firstName:String
   lastName:String
   fullName:String 
}

여기에는 fullName 필드 가 없습니다 .students.json파일. 그러나 쿼리를 통해 학생 의 전체 이름 을 가져와야합니다 . FULLNAME 님이 ,이 경우 데이터 소스를 사용할 수없는 사용자 정의 필드 것입니다.

3 단계-Resolver 생성

파일 생성 resolvers.js 프로젝트 폴더에 다음 코드를 추가하십시오-

const db = require('./db')
const Query = {
   //resolver function for greeting
   greeting:() => {
      return "hello from  TutorialsPoint !!!"
   },
   
   //resolver function for students returns list
   students:() => db.students.list(),

   //resolver function for studentbyId
   studentById:(root,args,context,info) => {
      //args will contain parameter passed in query
      return db.students.get(args.id);
   }
}

//for each single student object returned,resolver is invoked

const Student = {
   fullName:(root,args,context,info) => {
      return root.firstName+":"+root.lastName
   }
}

module.exports = {Query,Student}

4 단계-애플리케이션 실행

만들기 server.js파일. 환경 설정 장의 8 단계를 참조하십시오. 터미널에서 npm start 명령을 실행합니다  . 서버는 9000 포트에서 실행됩니다. 여기서는 GraphiQL을 클라이언트로 사용하여 애플리케이션을 테스트합니다.

브라우저를 열고 URL을 입력하십시오. http://localhost:9000/graphiql. 편집기에 다음 쿼리를 입력하십시오-

{
   students{
      id
      fullName
   }
}

쿼리에 대한 응답은 다음과 같습니다.

{
   "data": {
      "students": [
         {
            "id": "S1001",
            "fullName": "Mohtashim:Mohammad"
         },
         
         {
            "id": "S1002",
            "fullName": "Kannan:Sudhakaran"
         },
         
         {
            "id": "S1003",
            "fullName": "Kiran:Panigrahi"
         }
      ]
   }
}

만들기 server.js 다음 코드를 추가하십시오-

const bodyParser = require('body-parser');
const cors = require('cors');
const express = require('express');

const db = require('./db');
const port = 9000;
const app = express();

//loading type definitions from schema file
const fs = require('fs')
const typeDefs = fs.readFileSync('./schema.graphql',{encoding:'utf-8'})

//loading resolvers
const resolvers = require('./resolvers')

//binding schema and resolver
const {makeExecutableSchema} = require('graphql-tools')
const schema = makeExecutableSchema({typeDefs, resolvers})

//enabling cross domain calls and form post
app.use(cors(), bodyParser.json());

//enabling routes
const  {graphiqlExpress,graphqlExpress} = require('apollo-server-express')
app.use('/graphql',graphqlExpress({schema}))
app.use('/graphiql',graphiqlExpress({endpointURL:'/graphql'}))

//registering port
app.listen(port, () => console.info(`Server started on port ${port}`));

터미널에서 npm start 명령을 실행합니다. 서버는 9000 포트에서 실행됩니다. 여기서는 GraphiQL을 클라이언트로 사용하여 애플리케이션을 테스트합니다.

브라우저를 열고 URL을 입력하십시오. http://localhost:9000/graphiql. 편집기에 다음 쿼리를 입력하십시오-

{
   students{
      id
      fullName
   }
}

쿼리에 대한 응답은 다음과 같습니다.

{
   "data": {
      "students": [
         {
            "id": "S1001",
            "fullName": "Mohtashim:Mohammad"
         },
         {
            "id": "S1002",
            "fullName": "Kannan:Sudhakaran"
         },
         {
            "id": "S1003",
            "fullName": "Kiran:Panigrahi"
         }
      ]
   }
}

그림 2-중첩 쿼리

학생 세부 정보와 대학 세부 정보를 가져 오기위한 중첩 쿼리를 만들어 보겠습니다. 동일한 프로젝트 폴더로 작업합니다.

1 단계-스키마 편집

스키마 파일에 이미 학생 필드가 있습니다. 현장 대학을 추가하고 그 유형을 정의하겠습니다.

type College {
   id:ID!
   name:String
   location:String
   rating:Float
}

type Student {
   id:ID!
   firstName:String
   lastName:String
   fullName:String
   college:College
}

2 단계-resolver.js 수정

아래와 같이 대학 리졸버 기능을 추가해야합니다. 반환 된 각 학생 객체에 대해 대학 해석기 기능이 실행됩니다. 이 경우 resolver의 루트 매개 변수에는 student 가 포함 됩니다.

const Student = {
   fullName:(root,args,context,info) => {
      return root.firstName+":"+root.lastName
   },
   college:(root) => {
      return db.colleges.get(root.collegeId);
   }
}
module.exports = {Query,Student}

리졸버는 대학 컬렉션의 get 메서드를 호출하고 collegeId를 전달하여 각 학생의 대학을 반환합니다 . 우리는 collegeId를 통해 Student와 College 사이에 연관 관계가 있습니다.

3 단계-애플리케이션 테스트

터미널 창을 열고 프로젝트 폴더로 이동합니다. -npm start 명령을 입력합니다. 브라우저를 시작하고 URL을 입력하십시오.http://localhost:9000/graphiql.

GraphiQL 창에 다음 쿼리를 입력하십시오-

{
   students{
      id
      firstName
      college {
         id
         name
         location
         rating
      }
   }
}

쿼리에 대한 응답은 다음과 같습니다.

{
   "data": {
      "students": [
         {
            "id": "S1001",
            "firstName": "Mohtashim",
            "college": {
               "id": "col-102",
               "name": "CUSAT",
               "location": "Kerala",
               "rating": 4.5
            }
         },
         
         {
            "id": "S1002",
            "firstName": "Kannan",
            "college": {
               "id": "col-101",
               "name": "AMU",
               "location": "Uttar Pradesh",
               "rating": 5
            }
         },
         
         {
            "id": "S1003",
            "firstName": "Kiran",
            "college": {
               "id": "col-101",
               "name": "AMU",
               "location": "Uttar Pradesh",
               "rating": 5
            }
         }
      ]
   }
}

쿼리 변수 란 무엇입니까?

쿼리에 전달할 동적 값이있는 경우 변수를 사용하여 이러한 동적 값을 나타냅니다. 따라서 클라이언트 응용 프로그램에서 쿼리를 다시 사용할 수 있습니다.

삽화

쿼리 변수를 이해하는 간단한 응용 프로그램을 만들어 보겠습니다.

1 단계-스키마 파일 편집

문자열 매개 변수를 받아 문자열을 반환 하는 sayHello 필드를 추가 합니다. 이름 값은 클라이언트 응용 프로그램에서 동적입니다.

type Query {
   sayHello(name:String!):String
}

2 단계-resolver.js 파일 편집

다음 과 같이 매개 변수를 취하는 sayHello 해결자를 추가하십시오.

sayHello:(root,args,context,info) => `Hi ${args.name} GraphQL server says Hello to you!!`

3 단계-GraphiQL에서 쿼리 변수 선언

변수는 $ 뒤에 변수 이름으로 선언됩니다. 예 : $ myname_Variable.

$ myname_Variable이 선언되면 명명 된 쿼리 구문과 함께 사용해야합니다. 쿼리 myQuery는 문자열 값을 받아 아래와 같이 sayHello에 전달합니다.

query myQuery($myname_Variable:String!) { sayHello(name:$myname_Variable)
}

GraphiQL 클라이언트의 쿼리 변수 섹션에서 $ myname_Variable의 값을 JSON 개체로 설정합니다.

{
   "myname_Variable": "Mohtashim"
}

위 코드의 출력은 다음과 같습니다.

{
   "data": {
      "sayHello": "Hi Mohtashim GraphQL server says Hello to you!!"
   }
}

Enum에서 쿼리 변수를 사용하는 방법

필드 매개 변수가 다음과 같을 때 쿼리 변수를 사용하는 방법을 보겠습니다. enum type.

1 단계-schema.graphql 파일 편집

enum ColorType {
   RED
   BLUE
   GREEN
}

type Query {
   setFavouriteColor(color:ColorType):String
}

setFavouriteColor의 함수는 입력으로 ENUM 소요 문자열 값을 반환한다.

2 단계-resolvers.js 파일 편집

리졸버 함수 setFavouriteColorrootargs를합니다 . 런타임에 함수에 전달 된 열거 형 값은 args 매개 변수를 통해 액세스 할 수 있습니다.

setFavouriteColor:(root,args) => {
   return  "Your Fav Color is :"+args.color;
}

3 단계-GraphiQL에서 쿼리 변수 선언

쿼리 이름이 query_to_setColorColorType의 color_variable이라는 이름의 변수를 사용합니다. 이 변수는 setFavouriteColor 메소드에 전달됩니다.

query query_to_setColor($color_variable:ColorType) {
   setFavouriteColor(color:$color_variable)
}

GraphiQL의 쿼리 변수 섹션에 다음 코드를 입력하십시오.

{
   "color_variable":"RED"
}

응답은 다음과 같습니다.

{
   "data": {
      "setFavouriteColor": "Your Fav Color is: RED"
   }
}

이 장에서는 GraphQL의 뮤 테이션 쿼리를 배웁니다.

변형 쿼리는 데이터 저장소의 데이터를 수정하고 값을 반환합니다. 데이터를 삽입, 업데이트 또는 삭제하는 데 사용할 수 있습니다. 돌연변이는 스키마의 일부로 정의됩니다.

돌연변이 쿼리의 구문은 다음과 같습니다.

mutation{
   someEditOperation(dataField:"valueOfField"):returnType
}

삽화

변형 쿼리를 사용하여 데이터 저장소에 새 학생 레코드를 추가하는 방법을 이해하겠습니다.

1 단계-프로젝트에 필요한 종속성 다운로드 및 설치

Mutation-app이라는 이름으로 프로젝트 폴더를 만듭니다. 터미널에서 디렉토리를 mutate-app으로 변경하십시오. 환경 설정 장에 설명 된 3 ~ 5 단계를 따릅니다.

2 단계-schema.graphql 파일 생성

더하다 schema.graphql 프로젝트 폴더 muti-app에 파일을 추가하고 다음 코드를 추가하십시오.

type Query {
   greeting:String
}

type Mutation {
   createStudent(collegeId:ID,firstName:String,lastName:String):String
}

createStudent 함수는 문자열 유형을 반환합니다. 이것은 학생을 생성 한 후 생성되는 고유 식별자 (ID)입니다.

3 단계-resolver.js 파일 생성

프로젝트 폴더에 파일 resolvers.js를 생성하고 다음 코드를 추가합니다.

const db = require('./db')
const Mutation = {
   createStudent:(root,args,context,info) => {
      return db.students.create({collegeId:args.collegeId,
      firstName:args.firstName,
      lastName:args.lastName})
   }
}
const Query = {
   greeting:() => "hello"
}

module.exports = {Query,Mutation}

변형 함수는 데이터 저장소의 학생 컬렉션을 가리 킵니다. 새 student 를 추가하려면 students 컬렉션에서 create 메서드를 호출합니다. 인수의 개체는 쿼리에 전달되는 매개 변수를 포함합니다. 학생 컬렉션 의 생성 메소드 는 새로 생성 된 학생 객체의 ID를 반환합니다.

4 단계-애플리케이션 실행

만들기 server.js파일. 환경 설정 장의 8 단계를 참조하십시오. 터미널에서 npm start 명령을 실행합니다. 서버는 9000 포트에서 실행됩니다. 여기서는 GraphiQL을 클라이언트로 사용하여 애플리케이션을 테스트합니다.

다음 단계는 브라우저를 열고 URL을 입력하는 것입니다. http://localhost:9000/graphiql. 편집기에 다음 쿼리를 입력하십시오-

//college Id should be matched with data from colleges.json for easy retrieval

mutation {
   createStudent(collegeId:"col-2",firstName:"Tim",lastName:"George")
}

위의 쿼리는 student.json 파일에 학생 객체를 생성합니다. 쿼리는 고유 식별자를 반환합니다. 쿼리의 응답은 다음과 같습니다.

{
   "data": {
      "createStudent": "SkQtxYBUm"
   }
}

학생 객체가 생성되었는지 확인하기 위해 studentById 쿼리를 사용할 수 있습니다. 데이터 폴더에서 students.json 파일을 열어 ID를 확인할 수도 있습니다.

studentById 쿼리를 사용하려면 schema.graphql 아래와 같이-

type Query {
   studentById(id:ID!):Student
}

type Student {
   id:ID!
   firstName:String
   lastName:String
   collegeId:String
}

편집 resolver.js 아래 주어진 파일-

const db = require('./db')
const Query = {
   studentById:(root,args,context,info) => {
      return db.students.get(args.id);
   }
}

const Mutation = {
   createStudent:(root,args,context,info) => {
      return db.students.create({collegeId:args.collegeId,
      firstName:args.firstName,
      lastName:args.lastName})
   }
}

module.exports = {Query,Mutation}

다음은 돌연변이 쿼리에서 반환 된 고유 ID로 학생을 얻는 쿼리입니다.

{
    studentById(id:"SkQtxYBUm") {
    id
    firstName
    lastName
  }
}

서버의 응답은 다음과 같습니다.

{
   "data": {
      "studentById": {
         "id": "SkQtxYBUm",
         "firstName": "Tim",
         "lastName":"George"
      }
   }
}

Mutation에서 객체 반환

객체를 변형으로 반환하는 것이 가장 좋습니다. 예를 들어 클라이언트 응용 프로그램은 학생 및 대학 세부 정보를 가져 오려고합니다. 이 경우 두 가지 다른 요청을하는 대신 학생과 대학 세부 정보를 포함하는 객체를 반환하는 쿼리를 만들 수 있습니다.

1 단계-스키마 파일 편집

이름이 지정된 새 메소드 추가 addStudent 돌연변이 유형의 객체를 반환합니다. schema.graphql.

학생 세부 정보를 통해 대학 세부 정보에 액세스하는 방법을 알아 보겠습니다. 스키마 파일에 대학 유형을 추가합니다.

type Mutation {
   addStudent_returns_object(collegeId:ID,firstName:String,lastName:String):Student

   createStudent(collegeId:ID,firstName:String,lastName:String):String
}

type College {
   id:ID!
   name:String
   location:String
   rating:Float
}

type Student {
   id:ID!
   firstName:String
   lastName:String
   college:College
}

2 단계-resolvers.js 파일 업데이트

파일 업데이트 resolvers.js 프로젝트 폴더에 다음 코드를 추가하십시오-

const Mutation = {
   createStudent:(root,args,context,info) => {

      return db.students.create({
         collegeId:args.collegeId,
         firstName:args.firstName,
         lastName:args.lastName
      })
   },
   
   // new resolver function
   addStudent_returns_object:(root,args,context,info) => {
      const id = db.students.create({
         collegeId:args.collegeId,
         firstName:args.firstName,
         lastName:args.lastName
      })

      return db.students.get(id)
   }
}

//for each single student object returned,resolver is invoked
const Student = {
   college:(root) => {
      return db.colleges.get(root.collegeId);
   }
}

module.exports = {Query,Student,Mutation}

3 단계-서버를 시작하고 GraphiQL에 쿼리 요청 입력

다음으로 서버를 시작하고 다음 코드로 GraphiQL에서 쿼리를 요청합니다.

mutation {
   addStudent_returns_object(collegeId:"col-101",firstName:"Susan",lastName:"George") {
      id
      firstName
      college{
         id
         name
      }
   }
}

위의 쿼리는 새 학생을 추가하고 대학 개체와 함께 학생 개체를 검색합니다. 이렇게하면 서버로의 왕복 시간이 절약됩니다.

응답은 다음과 같습니다.

{
   "data": {
      "addStudent_returns_object": {
         "id": "rklUl08IX",
         "firstName": "Susan",
         "college": {
            "id": "col-101",
            "name": "AMU"
         }
      }
   }
}

데이터를 추가하거나 수정하는 동안 사용자 입력을 확인하는 것이 중요합니다. 예를 들어 필드 값이 항상 null이 아닌지 확인해야 할 수 있습니다. 우리는 사용할 수 있습니다! (non-nullable) GraphQL에 마커를 입력하여 이러한 유효성 검사를 수행합니다.

사용 구문 ! 유형 마커는 다음과 같습니다.

type TypeName {
   field1:String!,
   field2:String!,
   field3:Int!
}

위의 구문은 모든 필드가 널이 아닌지 확인합니다.

문자열 길이를 확인하거나 숫자가 주어진 범위 내에 있는지 확인하는 것과 같은 추가 규칙을 구현하려면 사용자 지정 유효성 검사기를 정의 할 수 있습니다. 사용자 지정 유효성 검사 논리는 리졸버 기능의 일부가됩니다. 예제의 도움으로 이것을 이해합시다.

그림-사용자 지정 유효성 검사기 구현

기본 유효성 검사가 포함 된 가입 양식을 만들어 보겠습니다. 양식에는 이메일, 이름 및 비밀번호 필드가 있습니다.

1 단계-프로젝트에 필요한 종속성 다운로드 및 설치

다음과 같은 폴더를 만듭니다. validation-app. 터미널에서 디렉터리를 validation-app으로 변경합니다. 환경 설정 장에 설명 된 3 ~ 5 단계를 따릅니다.

2 단계-스키마 생성

더하다 schema.graphql 프로젝트 폴더의 파일 validation-app 다음 코드를 추가하십시오-

type Query {
   greeting:String
}

type Mutation {
   signUp(input:SignUpInput):String
}

input SignUpInput {
   email:String!,
   password:String!,
   firstName:String!
}

Note− signUp 함수의 매개 변수 수를 줄이기 위해 입력 유형 SignUpInput을 사용할 수 있습니다. 따라서 signUp 함수는 SignUpInput 유형의 매개 변수를 하나만 사용합니다.

3 단계-리졸버 생성

파일 생성 resolvers.js 프로젝트 폴더에 다음 코드를 추가하십시오-

const Query = {
   greeting:() => "Hello"
}

const Mutation ={
   signUp:(root,args,context,info) => {

      const {email,firstName,password} = args.input;

      const emailExpression = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
      
      const isValidEmail =  emailExpression.test(String(email).toLowerCase())
      if(!isValidEmail)
      throw new Error("email not in proper format")

      if(firstName.length > 15)
      throw new Error("firstName should be less than 15 characters")

      if(password.length < 8 )
      throw new Error("password should be minimum 8 characters")
      
      return "success";
   }
}
module.exports = {Query,Mutation}

해석기 기능인 signUp은 매개 변수 이메일, 비밀번호 및 firstName을 허용합니다. 이는 args.input을 통해 액세스 할 수 있도록 입력 변수를 통해 전달됩니다.

4 단계-애플리케이션 실행

server.js 파일을 만듭니다. 환경 설정 장의 8 단계를 참조하십시오. 터미널에서 npm start 명령을 실행합니다 . 서버는 9000 포트에서 실행됩니다. 여기서는 GraphiQL을 클라이언트로 사용하여 애플리케이션을 테스트합니다.

브라우저를 열고 URL을 입력하십시오. http://localhost:9000/graphiql. 편집기에 다음 쿼리를 입력하십시오-

mutation doSignUp($input:SignUpInput) { signUp(input:$input)
}

가입 기능에 대한 입력은 복잡한 유형이므로 graphiql에서 쿼리 변수를 사용해야합니다. 이를 위해 먼저 쿼리에 이름을 지정하고 doSignUp이라고 이름을 지정해야합니다. $ input은 쿼리 변수입니다.

다음 쿼리 변수는 graphiql의 쿼리 변수 탭에 입력해야합니다.

{
   "input":{
      "email": "abc@abc",
      "firstName": "kannan",
      "password": "pass@1234"
   }
}

오류 배열에는 아래와 같이 유효성 검사 오류의 세부 정보가 포함되어 있습니다.

{
   "data": {
      "signUp": null
   },
   
   "errors": [
      {
         "message": "email not in proper format",
         "locations": [
            {
               "line": 2,
               "column": 4
            }
         ],
         "path": [
            "signUp"
         ]
      }
   ]
}

아래에 주어진 것처럼 각 필드에 대해 적절한 입력을 입력해야합니다.

{
   "input":{
      "email": "[email protected]",
      "firstName": "kannan",
      "password": "pass@1234"
   }
}

응답은 다음과 같습니다.

{
   "data": {
      "signUp": "success"
   }
}

여기에서 아래 쿼리에서는 암호를 할당하지 않습니다.

{
   "input":{
      "email": "[email protected]",
      "firstName": "kannan"
   }
}

필수 필드가 제공되지 않으면 qraphql 서버는 다음 오류를 표시합니다.

{
   "errors": [
      {
         "message": "Variable \"$input\" got invalid value {\"email\":\"[email protected]\",\"firstName\":\"kannan\"}; Field value.password of required type String! was not provided.",
         "locations": [
            {
               "line": 1,
               "column": 19
            }
         ]
      }
   ]
}

웹 애플리케이션은 데이터를 비동기 적으로 (백그라운드에서) 보내고 검색합니다. AJAX를 사용하면 웹 사이트에서 페이지를 새로 고치지 않고도 화면에 콘텐츠를로드 할 수 있습니다. jQuery는 AJAX 기능에 대한 여러 가지 방법을 제공하므로 AJAX를 더 쉽게 사용할 수 있습니다. 이 장에서는 GraphQL을 jQuery와 통합하는 방법을 배웁니다.

클라이언트 서버 아키텍처를 사용하는 애플리케이션을 고려하십시오. GraphQL 서버에서 데이터를 요청하는 프런트 엔드 웹 페이지를 만들 수 있습니다. 웹 페이지는 jQuery를 사용하여 GraphQL 서버에 AJAX 호출을합니다.

GraphQL을 JQuery와 통합하기 위해 GraphiQL 요청 헤더를 검사하고 요청 매개 변수를 이해하겠습니다.

시작 hello-world앱 (관련 그림은 6 장 참조). GraphiQL 창에 graphql 쿼리 {greeting}을 입력합니다. 크롬에서 마우스 오른쪽 버튼을 클릭하고 검사하거나 (ctrl + shift + I)를 눌러 아래와 같이 네트워크 탭으로 이동합니다.

단순한 것에서 hello-world 예를 들어, 우리는 http method 사용은 POST. 이제 브라우저에서 헤더 섹션까지 아래로 스크롤하여 요청 페이로드 를 확인합니다  .

클릭하면 view code, 크롬의 요청 페이로드 섹션에 다음이 표시됩니다.

{"query":"{\n  greeting\n}","variables":null,"operationName":null}

또한 요청 URL, http://localhost:9000/graphql 클라이언트 애플리케이션에서 호출해야합니다.

삽화

단계별 프로세스를 사용하여 GraphQL을 JQuery와 통합하는 방법을 이해하겠습니다.

서버 설정

다음 단계를 사용하여 서버를 설정하는 방법을 배웁니다.

1 단계-프로젝트에 필요한 종속성 다운로드 및 설치

다음과 같은 폴더를 만듭니다. jquery-server-app. 터미널에서 디렉토리를 jquery-server-app로 변경하십시오. 환경 설정 장에 설명 된 3 ~ 5 단계를 따릅니다.

2 단계-스키마 생성

프로젝트 폴더에 schema.graphql 파일 추가 jquery-server-app 다음 코드를 추가하십시오-

type Query
{
   greeting: String
   sayHello(name:String!):String
}

파일이 두 개의 쿼리를 정의했습니다. greetingsayHello. sayHello 쿼리는 문자열 매개 변수를 받아들이고 다른 문자열을 반환합니다. sayHello () 함수에 대한 매개 변수가 null이 아닙니다.

3 단계-리졸버 생성

프로젝트 폴더에 파일 resolvers.js를 생성하고 다음 코드를 추가합니다.

const Query =
{
   greeting: () => 'Hello GraphQL  From TutorialsPoint !!' ,
   sayHello:(root,args,context,info) =>  `Hi ${args.name} GraphQL server says Hello to you!!`
}
module.exports = {Query}

여기, greetingsayHello두 해결 자입니다. sayHello 해석기에서 name 매개 변수에 전달 된 값은 args를 통해 액세스 할 수 있습니다. 모듈 외부에서 해석기 기능에 액세스하려면 Query 객체를 다음을 사용하여 내 보내야합니다.module.exports.

4 단계-애플리케이션 실행

server.js 파일을 만듭니다. 환경 설정 장의 8 단계를 참조하십시오. 터미널에서 npm start 명령을 실행합니다 . 서버는 9000 포트에서 실행됩니다. 여기서는 GraphiQL을 클라이언트로 사용하여 애플리케이션을 테스트합니다.

브라우저를 열고 URL을 입력하십시오. http://localhost:9000/graphiql. 편집기에 다음 쿼리를 입력하십시오-

{
   greeting,
   sayHello(name:"Mohtashim")
}

서버의 응답은 다음과 같습니다.

{
   "data": {
      "greeting": "Hello GraphQL From TutorialsPoint !!",
      "sayHello": "Hi Mohtashim GraphQL server says Hello to you!!"
   }
}

클라이언트 설정

이미 서버를 설정 했으므로 이제 클라이언트 설정 방법을 배웁니다.

1 단계-현재 프로젝트 폴더 외부에 새 폴더 jquery-client-app 생성

먼저 jquery-client-app 프로젝트 폴더 외부.

2 단계-jQuery 통합을위한 HTML 페이지 index.html 생성

jquery에서 클라이언트 응용 프로그램을 만들고 두 메서드를 모두 호출합니다. 다음은 코드입니다. index.html 파일. 그만큼 index.html 페이지에서 버튼을 누르면 서버에 요청을 보냅니다. GreetSayHello클릭됩니다. $ .ajax () 함수를 사용하여 비동기 요청을합니다.

<!DOCTYPE html>
<html>
   <head>
      <script src = "https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
      <script>
         $(document).ready(function() { $("#btnSayhello").click(function() {

               const name = $("#txtName").val(); console.log(name); $("#SayhelloDiv").html('loading....');

               $.ajax({url: "http://localhost:9000/graphql", contentType: "application/json",type:'POST', data: JSON.stringify({ query:`{ sayHello(name:"${name}")}`
                  }),
                  success: function(result) {
                     console.log(JSON.stringify(result))
                     $("#SayhelloDiv").html("<h1>"+result.data.sayHello +"</h1>"); } }); }); $("#btnGreet").click(function() {
               $("#greetingDiv").html('loading....'); //https://kannan-first-graphql-app.herokuapp.com/graphql $.ajax({url: "http://localhost:9000/graphql",
                  contentType: "application/json",
                  type:'POST',
                  data: JSON.stringify({
                     query:`{greeting}`
                  }),
                  success: function(result) {
                     $("#greetingDiv").html("<h1>"+result.data.greeting+"</h1>");
                  }
               });
            });
         });
      </script>
   </head>
   
   <body>
      <h1>Jquery Client </h1>

      <hr/>
      <section>
         <button id = "btnGreet">Greet</button>
         <br/> <br/>
         <div id = "greetingDiv"> </div>
      </section>
      
      <br/> <br/> <br/>
      <hr/>

      <section>
         Enter a name:<input id = "txtName" type = "text" value = "kannan"/>
         <button id = "btnSayhello">SayHello</button>
         <div id = "SayhelloDiv"> </div>
      </section>
   </body>
</html>

브라우저에서이 파일을 열고 버튼을 클릭하여 응답을 확인하십시오. 출력은 다음과 같습니다.

React는 사용자 인터페이스를 구축하기위한 Javascript 라이브러리입니다. 이 장에서는 GraphQL을 React 애플리케이션과 통합하는 방법을 설명합니다.

삽화

반응 프로젝트를 설정하는 가장 빠른 방법은 Create React App  도구를 사용하는 것  입니다. 다음 섹션에서는 서버와 클라이언트를 모두 설정하는 방법을 배웁니다.

서버 설정

서버를 설정하려면 아래 단계를 따르십시오.

1 단계-프로젝트에 필요한 종속성 다운로드 및 설치

폴더 생성 react-server-app. 디렉토리를 다음으로 변경하십시오. react-server-app 터미널에서. 환경 설정 장에 설명 된 3 ~ 5 단계를 따릅니다.

2 단계-스키마 생성

더하다 schema.graphql 프로젝트 폴더의 파일 react-server-app 다음 코드를 추가하십시오-

type Query
{
   greeting: String
   sayHello(name:String!):String
}

이 파일은 greeting과 sayHello라는 두 가지 쿼리를 정의했습니다. sayHello 쿼리는 문자열 매개 변수를 받아들이고 다른 문자열을 반환합니다. sayHello () 함수에 대한 매개 변수가 null이 아닙니다.

3 단계-리졸버 생성

파일 생성 resolvers.js 프로젝트 폴더에 다음 코드를 추가하십시오-

const Query =
{
   greeting: () => 'Hello GraphQL  From TutorialsPoint !!' ,
   sayHello:(root,args,context,info) =>  `Hi ${args.name} GraphQL server says Hello to you!!`
}
module.exports = {Query}

여기서 greeting과 sayHello는 두 명의 해결 자입니다. sayHello 해석기에서 name 매개 변수에 전달 된 값은 args를 통해 액세스 할 수 있습니다. 모듈 외부에서 리졸버 기능에 액세스하려면 module.exports를 사용하여 Query 객체를 내 보내야합니다.

4 단계-애플리케이션 실행

server.js 파일을 만듭니다. 환경 설정 장의 8 단계를 참조하십시오. 터미널에서 npm start 명령을 실행합니다 . 서버는 9000 포트에서 실행됩니다. 여기서는 GraphiQL을 클라이언트로 사용하여 애플리케이션을 테스트합니다.

브라우저를 열고 URL을 입력하십시오. http://localhost:9000/graphiql. 편집기에 다음 쿼리를 입력하십시오-

{
   greeting,
   sayHello(name:"Mohtashim")
}

서버의 응답은 다음과 같습니다.

{
   "data": {
      "greeting": "Hello GraphQL  From TutorialsPoint !!",
      "sayHello": "Hi Mohtashim GraphQL server says Hello to you!!"
   }
}

클라이언트 설정

클라이언트 용 새 터미널을 엽니 다. 클라이언트 응용 프로그램을 실행하기 전에 서버 터미널을 계속 실행해야합니다. React 애플리케이션은 포트 번호 3000에서 실행되고 서버 애플리케이션은 포트 번호 9000에서 실행됩니다.

1 단계-React 프로젝트 만들기 hello-world-client

클라이언트 터미널에서 다음 명령을 입력하십시오-

npx create-react-app hello-world-client

이것은 일반적인 반응 애플리케이션에 필요한 모든 것을 설치합니다. 그만큼npx 유틸리티 및 create-react-app도구는 hello-world-client라는 이름으로 프로젝트를 만듭니다. 설치가 완료되면 VSCode에서 프로젝트를 엽니 다.

2 단계-hello-world-client 시작

터미널의 현재 폴더 경로를 hello-world-client로 변경합니다. npm start를 입력하여 프로젝트를 시작합니다. 그러면 포트 3000에서 개발 서버가 실행되고 자동으로 브라우저가 열리고 색인 페이지가로드됩니다.

이것은 아래 주어진 스크린 샷에 나와 있습니다.

3 단계-앱 구성 요소 수정

src 폴더 내의 App.js에서 두 개의 함수를 추가하십시오. 하나는 인사말을로드하고 다른 하나는 sayHello 메시지를로드합니다.

다음은 인사말을 위해 GraphQL 쿼리를 보내는 loadGreeting 함수입니다.

async function loadGreeting() {
   const response = await fetch('http://localhost:9000/graphql', {
      method:'POST',

      headers:{'content-type':'application/json'},
      body:JSON.stringify({query:'{greeting}'})
   })

   const rsponseBody = await response.json();
   return rsponseBody.data.greeting;

   console.log("end of function")
}

다음은 loadSayhello sayHello에 대한 GraphQL 쿼리를 보내는 함수-

async function  loadSayhello(name) {
   const response = await fetch('http://localhost:9000/graphql', {
      method:'POST',
      headers:{'content-type':'application/json'},
      body:JSON.stringify({query:`{sayHello(name:"${name}")}`})
   })
}

완전한 App.js 파일은 다음과 같습니다-

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

async function loadGreeting() {
   const response =  await fetch('http://localhost:9000/graphql', {
      method:'POST',
      headers:{'content-type':'application/json'},
      body:JSON.stringify({query:'{greeting}'})
   })
   const rsponseBody =  await response.json();
   return rsponseBody.data.greeting;
   console.log("end of function")
}

async function  loadSayhello(name) {
   const response =  await fetch('http://localhost:9000/graphql', {
      method:'POST',
      headers:{'content-type':'application/json'},
      body:JSON.stringify({query:`{sayHello(name:"${name}")}`})
   })
   const rsponseBody =  await response.json();
   return rsponseBody.data.sayHello;
}

class App extends Component {
   constructor(props) {
      super(props);
      this.state =  {greetingMessage:'',sayHelloMessage:'',userName:''}
      this.updateName =  this.updateName.bind(this);
      this.showSayHelloMessage =  this.showSayHelloMessage.bind(this);
      this.showGreeting =  this.showGreeting.bind(this);
   }
   
   showGreeting() {
      loadGreeting().then(g => this.setState({greetingMessage:g+" :-)"}))
   }
   
   showSayHelloMessage() {
      const name = this.state.userName;
      console.log(name)
      loadSayhello(name).then(m => this.setState({sayHelloMessage:m}))
   }
   
   updateName(event) {
      this.setState({userName:event.target.value})
   }
   render() {
      return (
         <div className = "App">
            <header className = "App-header">
               <img src = {logo} className = "App-logo" alt = "logo" />
               <h1 className = "App-title">Welcome to React</h1>
            </header>
            <br/><br/>
            <section>
               <button id = "btnGreet" onClick = {this.showGreeting}>Greet</button>
               <br/> <br/>
               <div id = "greetingDiv">
                  <h1>{this.state.greetingMessage}</h1>
               </div>
            </section>
            
            <hr/>
            
            <section>
               Enter a name:<input id = "txtName" type = "text" onChange = {this.updateName}
               value = {this.state.userName}/>
               <button id = "btnSayhello" onClick = {this.showSayHelloMessage}>SayHello</button>
               <br/>
               user name is:{this.state.userName}    <br/>
               <div id = "SayhelloDiv">
                  <h1>{this.state.sayHelloMessage}</h1>
               </div>
            </section>
         </div>
      );
   }
}

export default App;

두 응용 프로그램이 모두 실행되면 인사 버튼을 클릭합니다. 그런 다음 텍스트 상자에 이름을 입력하고 sayHello 버튼을 클릭합니다. 출력은 다음과 같습니다.

우리는 Apollo Server를 사용하여 서버 측에서 graphql 사양을 구축했습니다. 생산 준비가 된 GraphQL 서버를 빠르고 쉽게 구축 할 수 있습니다. 이제 클라이언트 측을 이해하겠습니다.

Apollo Client는 GraphQL을 사용하여 클라이언트 애플리케이션을 구축하는 가장 좋은 방법입니다. 이 클라이언트는 개발자가 GraphQL로 데이터를 가져 오는 UI를 빠르게 구축 할 수 있도록 설계되었으며 모든 JavaScript 프런트 엔드에서 사용할 수 있습니다.

Apollo Client는 다음 플랫폼을 지원합니다.

Sr. 아니. 플랫폼 및 프레임 워크
1

Javascript

React, Angular, Vue, Meteor, Ember

2

WebComponents

폴리머, 리타 폴로

Native Mobile

Java가 포함 된 네이티브 Android, Swift가 포함 된 네이티브 iOS

캐싱은 Apollo Client의 주요 기능 중 하나입니다. apollo-boost는 많은 다른 의존성을 가져 오는 편리한 패키지입니다.

삽화

다음 단계를 사용하여 Apollo Client를 사용하여 클라이언트 응용 프로그램을 구축하는 방법을 살펴 보겠습니다.

서버 설정

서버를 설정하려면 아래 단계를 따라야합니다.

1 단계-프로젝트에 필요한 종속성 다운로드 및 설치

apollo-server-app 폴더를 만듭니다. 디렉토리를 다음으로 변경하십시오. apollo-server-app 터미널에서. 그런 다음 환경 설정 장에 설명 된 3 ~ 5 단계를 따릅니다.

2 단계-스키마 생성

더하다 schema.graphql 프로젝트 폴더의 파일 apollo-server-app 다음 코드를 추가하십시오-

type Query
{
   students:[Student]
}

type Student {
   id:ID!
   firstName:String
   lastName:String
   college:College
}

type College {
   id:ID!
   name:String
   location:String
   rating:Float
}

3 단계-해석기 추가

파일 생성 resolvers.js 프로젝트 폴더에 다음 코드를 추가하십시오-

const db = require('./db')

const Query = {
   //resolver function for students returns list
   students:() => db.students.list(),
}

const Student = {
   college:(root) => {
      return db.colleges.get(root.collegeId);
   }
}
module.exports = {Query,Student}

4 단계-애플리케이션 실행

만들기 server.js파일. 환경 설정 장의 8 단계를 참조하십시오.  터미널에서 npm start 명령을 실행합니다  . 서버는 9000 포트에서 실행됩니다. 여기서는 GraphiQL을 클라이언트로 사용하여 애플리케이션을 테스트합니다.

브라우저를 열고 URL을 입력하십시오. http://localhost:9000/graphiql. 편집기에 다음 쿼리를 입력하십시오.

{
   students{
      id
      firstName
      college{
         name
      }
   }
}

쿼리에 대한 응답은 다음과 같습니다.

{
   "data": {
      "students": [
         {
            "id": "S1001",
            "firstName": "Mohtashim",
            "college": {
               "name": "CUSAT"
            }
         },
         
         {
            "id": "S1002",
            "firstName": "Kannan",
            "college": {
               "name": "AMU"
            }
         },
         
         {
            "id": "S1003",
            "firstName": "Kiran",
            "college": {
               "name": "AMU"
            }
         }
      ]
   }
}

클라이언트 설정

클라이언트 용 새 터미널을 엽니 다. 클라이언트 응용 프로그램을 실행하기 전에 서버 터미널을 계속 실행해야합니다. React 애플리케이션은 포트 번호 3000에서 실행되고 서버 애플리케이션은 포트 번호 9000에서 실행됩니다.

1 단계-React 애플리케이션 생성

클라이언트 터미널에서 다음 명령을 입력하십시오-

npx create-react-app hello-world-client

이것은 일반적인 반응 애플리케이션에 필요한 모든 것을 설치합니다. npx 유틸리티 및 create-react-app 도구는 이름으로 프로젝트를 만듭니다.hello-world-client. 설치가 완료되면 VSCode에서 프로젝트를 엽니 다.

2 단계-hello-world-client 시작

터미널의 현재 폴더 경로를 다음으로 변경하십시오. hello-world-client. npm start를 입력하여 프로젝트를 시작합니다. 그러면 포트 3000에서 개발 서버가 실행되고 자동으로 브라우저가 열리고 색인 페이지가로드됩니다.

이것은 아래 주어진 스크린 샷에 나와 있습니다.

3 단계-Apollo 클라이언트 라이브러리 설치

Apollo Client를 설치하려면 새 터미널을 열고 현재 프로젝트 폴더 경로에 있어야합니다. 다음 명령을 입력하십시오-

npm install apollo-boost graphql

그러면 클라이언트 측용 graphql 라이브러리와 Apollo Boost 패키지가 다운로드됩니다. apollo-boost 종속성에 npm view를 입력하여이를 교차 확인할 수 있습니다. 이것은 아래와 같이 많은 의존성을 가질 것입니다-

{
   '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 파일에서 앱 구성 요소 수정

Apollo Client를 사용하면 fetch API를 사용하지 않고 서버를 직접 호출 할 수 있습니다. 또한 쿼리 및 변형은 백틱 표기법으로 만든 문자열에 포함되지 않아야합니다. 이것은gql함수는 쿼리를 직접 구문 분석합니다. 즉, 프로그래머는 GraphiQL 도구에서 쿼리를 작성할 때와 동일한 방식으로 쿼리를 직접 작성할 수 있습니다. gql 백틱 표기법으로 작성된 템플릿 문자열을 graphql 쿼리 객체로 구문 분석하는 태그 함수입니다. Apollo Client 쿼리 메서드는 promise를 반환합니다.

다음 코드 스 니펫은 Apollo Client를 가져 오는 방법을 보여줍니다.

import {ApolloClient, HttpLink, InMemoryCache} from 'apollo-boost'

const endPointUrl = 'http://localhost:9000/graphql'
const client = new ApolloClient({
   link: new HttpLink({uri:endPointUrl}),
   cache:new InMemoryCache()
});

이전 장에서 HTTP 요청에 대해 API 가져 오기를 사용하는 방법에 대해 설명했습니다. 다음 코드는 사용 방법을 보여줍니다.gql함수. 그만큼loadStudentsAsync 함수는 graphql 클라이언트를 사용하여 서버를 쿼리합니다.

async function loadStudentsAsync() {
   const query = gql`
   {
      students{
         id
         firstName
         lastName
         college{
            name
         }
      }
   }`
   const {data} = await client.query({query}) ;
   return data.students;
}

당신은 index.jssrc공용 폴더의 폴더 및 index.html; 자동 생성 된 다른 모든 파일은 제거 할 수 있습니다.

디렉토리 구조는 다음과 같습니다.

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

다음은 index.js 반응 응용 프로그램에서-

import React, {Component} from 'react';
import ReactDOM from 'react-dom';

// apollo client

import {ApolloClient, HttpLink, InMemoryCache} from 'apollo-boost'
import gql from 'graphql-tag'

const endPointUrl = 'http://localhost:9000/graphql'
const client = new ApolloClient({
   link: new HttpLink({uri:endPointUrl}),
   cache:new InMemoryCache()
});

async function loadStudentsAsync() {
   const query = gql`
   {
      students{
         id
         firstName
         lastName
         college{
            name
         }
      }
   }
   `
   const {data} = await client.query({query}) ;
   return data.students;
}
class  App  extends Component {
   constructor(props) {
      super(props);
      this.state = {
         students:[]
      }
      this.studentTemplate =  [];
   }
   async loadStudents() {
      const studentData =  await loadStudentsAsync();
      this.setState({
         students: studentData
      })
      console.log("loadStudents")
   }
   render() {
      return(
         <div>
            <input type = "button"  value = "loadStudents" onClick = {this.loadStudents.bind(this)}/>
            <div>
               <br/>
               <hr/>
               <table border = "3">
                  <thead>
                     <tr>
                        <td>First Name</td>
                        <td>Last Name</td>
                        <td>college Name</td>
                     </tr>
                  </thead>
                  
                  <tbody>
                     {
                        this.state.students.map(s => {
                           return (
                              <tr key = {s.id}>
                                 <td>
                                    {s.firstName}
                                 </td>
                                 <td>
                                    {s.lastName}
                                 </td>
                                 <td>
                                    {s.college.name}
                                 </td>
                              </tr>
                           )
                        })
                     }
                  </tbody>
               </table>
            </div>
         </div>
      )
   }
}
ReactDOM.render(<App/>, document.getElementById('root'));

React 애플리케이션은 아래와 같이 loadStudents 버튼을 클릭하면 GraphQL 서버에서 학생들을로드합니다.

인증은 사용자 또는 프로세스의 ID를 확인하는 프로세스 또는 작업입니다. 익명 사용자가 데이터를 사용할 수 없도록 애플리케이션이 사용자를 인증하는 것이 중요합니다. 이 섹션에서는 GraphQL 클라이언트를 인증하는 방법을 배웁니다.

익스프레스 JWT

이 예에서는 jQuery를 사용하여 클라이언트 응용 프로그램을 만듭니다. 요청을 인증하기 위해 우리는 express-jwt 서버 측의 모듈.

express-jwt 모듈은 JWT 토큰을 사용하여 HTTP 요청을 인증 할 수있는 미들웨어입니다. JWT (JSON Web Token)는 로그인 한 사용자를 식별하는 긴 문자열입니다.

사용자가 성공적으로 로그인하면 서버는 JWT 토큰을 생성합니다. 이 토큰은 로그를 명확하게 식별합니다. 즉, 토큰은 사용자의 신원을 나타냅니다. 따라서 다음에 클라이언트가 서버에 올 때 필요한 리소스를 얻기 위해이 토큰을 제시해야합니다. 클라이언트는 모바일 애플리케이션 또는 웹 애플리케이션 일 수 있습니다.

삽화

이 그림을 이해하기 위해 단계별 절차를 따릅니다.

서버 설정

다음은 서버를 설정하는 단계입니다.

1 단계-프로젝트에 필요한 종속성 다운로드 및 설치

폴더 생성 auth-server-app. 디렉토리를 다음으로 변경하십시오. auth-server-app 터미널에서. 환경 설정 장에 설명 된 3 ~ 5 단계를 따릅니다.

2 단계-스키마 생성

schema.graphql auth-server-app
type Query
{
   greetingWithAuth:String
}

3 단계-해석기 추가

파일 생성 resolvers.js 프로젝트 폴더에 다음 코드를 추가하십시오-

확인자는 GraphQL의 컨텍스트 개체에서 인증 된 사용자 개체를 사용할 수 있는지 확인합니다. 인증 된 사용자를 사용할 수없는 경우 예외가 발생합니다.

const db = require('./db')

const Query = {
   greetingWithAuth:(root,args,context,info) => {

      //check if the context.user is null
      if (!context.user) {
         throw new Error('Unauthorized');
      }
      return "Hello from TutorialsPoint, welcome back : "+context.user.firstName;
   }
}

module.exports = {Query}

4 단계-Server.js 파일 생성

인증 미들웨어는 JSON 웹 토큰을 사용하여 호출자를 인증합니다. 인증 용 URL은 다음과 같습니다. http://localhost:9000/login.

이것은 사후 작업입니다. 사용자는 백엔드에서 확인 될 이메일과 비밀번호를 제출해야합니다. jwt.sign 메소드를 사용하여 유효한 토큰이 생성되면 클라이언트는 후속 요청을 위해이를 헤더로 보내야합니다.

토큰이 유효한 경우 req.user는 권한 부여 및 액세스 제어를 위해 나중에 미들웨어에서 사용하도록 디코딩 된 JSON 개체로 설정됩니다.

다음 코드는 요청을 인증하기 위해 jsonwebtoken과 express-jwt의 두 모듈을 사용합니다.

  • 사용자가 greet버튼을 누르면 / graphql 경로에 대한 요청이 발행됩니다. 사용자가 인증되지 않은 경우 자신을 인증하라는 메시지가 표시됩니다.

  • 사용자에게 이메일 ID와 비밀번호를 허용하는 양식이 제공됩니다. 이 예에서 / login 경로는 사용자 인증을 담당합니다.

  • / login 경로는 데이터베이스에서 사용자가 제공 한 자격 증명과 일치하는 항목이 있는지 확인합니다.

  • 자격 증명이 유효하지 않은 경우 HTTP 401 예외가 사용자에게 반환됩니다.

  • 자격 증명이 유효하면 서버에서 토큰을 생성합니다. 이 토큰은 사용자에 대한 응답의 일부로 전송됩니다. 이것은 jwt.sign 함수에 의해 수행됩니다.

const expressJwt = require('express-jwt');
const jwt = require('jsonwebtoken');

//private key
const jwtSecret = Buffer.from('Zn8Q5tyZ/G1MHltc4F/gTkVJMlrbKiZt', 'base64');

app.post('/login', (req, res) => {
   const {email, password} = req.body;
   
   //check database
   const user = db.students.list().find((user) =>  user.email === email);
   if (!(user && user.password === password)) {
      res.sendStatus(401);
      return;
   }
   
   //generate a token based on private key, token doesn't have an expiry
   const token = jwt.sign({sub: user.id}, jwtSecret);
   res.send({token});
});

모든 요청에 ​​대해 app.use () 함수가 호출됩니다. 이것은 차례로 expressJWT 미들웨어를 호출합니다. 이 미들웨어는 JSON 웹 토큰을 디코딩합니다. 토큰에 저장된 사용자 ID는 요청 객체에 속성 사용자로 검색 및 저장됩니다.

//decodes the JWT and stores in request object
app.use(expressJwt({
   secret: jwtSecret,
   credentialsRequired: false
}));

GraphQL 컨텍스트 내에서 사용자 속성을 사용할 수 있도록하기 위해이 속성은 context 아래와 같이 객체-

//Make req.user available to GraphQL context
app.use('/graphql', graphqlExpress((req) => ({
   schema,
   context: {user: req.user &&apm; db.students.get(req.user.sub)}
})));

창조하다 server.js 현재 폴더 경로에서. 완전한 server.js 파일은 다음과 같습니다.

const bodyParser = require('body-parser');
const cors = require('cors');
const express = require('express');
const expressJwt = require('express-jwt'); //auth
const jwt = require('jsonwebtoken'); //auth
const db = require('./db');

var port = process.env.PORT || 9000
const jwtSecret = Buffer.from('Zn8Q5tyZ/G1MHltc4F/gTkVJMlrbKiZt', 'base64');
const app = express();

const fs = require('fs')
const typeDefs = fs.readFileSync('./schema.graphql',{encoding:'utf-8'})
const resolvers = require('./resolvers')
const {makeExecutableSchema} = require('graphql-tools')

const schema = makeExecutableSchema({typeDefs, resolvers})

app.use(cors(), bodyParser.json(), expressJwt({
   secret: jwtSecret,
   credentialsRequired: false
}));

const  {graphiqlExpress,graphqlExpress} = require('apollo-server-express')

app.use('/graphql', graphqlExpress((req) => ({
   schema,
   context: {user: req.user && db.students.get(req.user.sub)}
})));
app.use('/graphiql',graphiqlExpress({endpointURL:'/graphql'}))

//authenticate students
app.post('/login', (req, res) => {
   const email = req.body.email;
   const password = req.body.password;

   const user = db.students.list().find((user) =>  user.email === email);
   if (!(user && user.password === password)) {
      res.sendStatus(401);
      return;
   }
   const token = jwt.sign({sub: user.id}, jwtSecret);
   res.send({token});
});

app.listen(port, () => console.info(`Server started on port ${port}`));

5 단계-애플리케이션 실행

터미널에서 npm start 명령을 실행합니다  . 서버는 9000 포트에서 실행됩니다. 여기서는 GraphiQL을 클라이언트로 사용하여 애플리케이션을 테스트합니다.

브라우저를 열고 URL을 입력하십시오. http://localhost:9000/graphiql. 편집기에 다음 쿼리를 입력하십시오-

{
   greetingWithAuth
}

아래 응답에서 인증 된 사용자가 아니므로 오류가 발생했습니다.

{
   "data": {
      "greetingWithAuth": null
   },
   "errors": [
      {
         "message": "Unauthorized",
         "locations": [
            {
               "line": 2,
               "column": 3
            }
         ],
         "path": [
            "greetingWithAuth"
         ]
      }
   ]
}

다음 섹션에서는 인증 할 클라이언트 애플리케이션을 만들어 보겠습니다.

JQuery 클라이언트 설정

클라이언트 응용 프로그램에서 스키마를 호출하는 인사 버튼이 제공됩니다. greetingWithAuth. 로그인없이 버튼을 클릭하면 아래와 같은 오류 메시지가 나타납니다.

데이터베이스에서 사용 가능한 사용자로 로그인하면 다음 화면이 나타납니다.

액세스 greeting, 먼저 URL에 액세스해야합니다. http://localhost:9000/login 아래와 같이 경로.

응답에는 서버에서 생성 된 토큰이 포함됩니다.

$.ajax({
   url:"http://localhost:9000/login",
   contentType:"application/json",
   type:"POST",
   data:JSON.stringify({email,password}),
   success:function(response) {
      loginToken = response.token;
      $('#authStatus') .html("authenticated successfully") .css({"color":"green",'font-weight':'bold'}); $("#greetingDiv").html('').css({'color':''});
   },
   error:(xhr,err) =>  alert('error')
})

로그인에 성공하면 아래와 같이 greetingWithAuth 스키마에 액세스 할 수 있습니다 . Bearer 토큰을 사용하는 모든 후속 요청에는 Authorizationheader가 있어야합니다.

{ 
   url: "http://localhost:9000/graphql",
   contentType: "application/json",
   headers: {"Authorization": 'bearer '+loginToken},  type:'POST',
   data: JSON.stringify({
   query:`{greetingWithAuth}`
}

다음은 index.html의 코드입니다-

<!DOCTYPE html>
<html>
   <head>
      <script src = "https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
      <script>
         $(document).ready(function() { let loginToken = ""; $("#btnGreet").click(function() {
                  $.ajax({url: "http://localhost:9000/graphql", contentType: "application/json", headers: {"Authorization": 'bearer '+loginToken}, type:'POST', data: JSON.stringify({ query:`{greetingWithAuth}` }), success: function(result) { $("#greetingDiv").html("<h1>"+result.data.greetingWithAuth+"</h1>")
                  },
                  error:function(jQxhr,error) {
                     if(jQxhr.status == 401) {
                        $("#greetingDiv").html('please authenticate first!!') .css({"color":"red",'font-weight':'bold'}) return; } $("#greetingDiv").html('error').css("color","red");
                  }
               });
            });
            $('#btnAuthenticate').click(function() { var email = $("#txtEmail").val();
               var password =  $("#txtPwd").val(); if(email && password) { $.ajax({
                     url:"http://localhost:9000/login",
                     contentType:"application/json",
                     type:"POST",
                     data:JSON.stringify({email,password}),
                     success:function(response) {
                        loginToken =  response.token;
                        $('#authStatus') .html("authenticated successfully") .css({"color":"green",'font-weight':'bold'}); $("#greetingDiv").html('').css({'color':''});
                     },
                     error:(xhr,err) =>  alert('error')
                  })
               }else alert("email and pwd empty")
            })
         });
      </script>
   </head>
   
   <body>
      <h1> GraphQL Authentication </h1>
      <hr/>
      <section>
         <button id = "btnGreet">Greet</button>
         <br/> <br/>
         <div id = "greetingDiv"></div>
      </section>
      <br/> <br/> <br/>
      <hr/>
      
      <section id = "LoginSection">
         <header>
            <h2>*Login first to  access greeting </h2>
         </header>
         <input type = "text" value = "[email protected]" placeholder = "enter email" id = "txtEmail"/>
         <br/>
         
         <input type = "password" value = "pass123" placeholder = "enter password" id = "txtPwd"/>
         <br/>
         
         <input type = "button" id = "btnAuthenticate"  value = "Login"/>
         <p id = "authStatus"></p>
      </section>
   </body>
</html>

캐싱은 임시 저장 영역에 데이터를 저장하는 프로세스입니다. 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 서버의 시간이 항상 최신이므로 데이터가 캐시되지 않음을 알 수 있습니다.