Graph QL, React, Apollo 클라이언트 및 Apollo 서버 응용 프로그램을 사용하는 방법

이것은 두 부분으로 구성된 시리즈다.첫 번째 부분에서 우리는graphql가 무엇인지, 그리고 그 장점을 이해하고graphql로 백엔드를 구축할 것이다.두 번째 부분에서, 우리는 Apollo 클라이언트를 사용하여 우리의graphql 지원을 우리의react 전단 서비스에 통합하는 것을 배울 것이다.이 시리즈는 최초로 나의 개인 블로그에 발표되었다.너는 아래에서 이 두 부분의 링크를 찾을 수 있다
  • How to Get Started With a Graph QL, React, Apollo Client, and Apollo Server App
  • How to Get Started With a Graph QL, React, Apollo Client, and Apollo Server App- Part 2
  • Graphql은 이미 오랫동안 존재해 왔다. 우리는 항상 Graphql가 복잡한 일이라고 생각하지만, 사실상 모든 Graphql는 서버와 클라이언트 간에 어떻게 HTTP를 통해 데이터를 교환하는지에 대한 규범이다.이것은 본질적으로 API에 사용되는 조회 언어로 서버에서 어떤 데이터를 얻을 수 있는지 정의한다.현재 이것은 표준 API에서 사용할 수 있는 모든 것과 다르다. 표준 API에서 특정한 데이터를 가져오는 데 사용할 특정한 단점이 있습니다.중간 API와 마찬가지로 특정 사용자에게 모든 글을 되돌려주는 /api/allarticles/:userId API가 있을 수 있습니다.이것은 API를 구축하는 기초이다. 우리는 이미 이런 기술로 API를 구축한 지 오래되었다. 그 전에 우리는 SOAP를 가지고 그 중에서 XML 데이터 구조를 사용했다.지금graphql가 REST의 사상을 개선했다면, 그것은 또 무엇이 다른가.rest의 경우, 우리는 URL을 클릭하고 데이터를 얻습니다.graphql의 경우, 우리는 우리가 무엇을 찾고 있는지 명확하게 묻고, 특정한 페이지를 구축하고자 하는 특정한 서브집합만 얻을 수 있습니다.

    입문


    이제 이 작은 소개 후에 우리는 직접 시범에 들어가자.이 프레젠테이션에서 우리는 Apollo Client를 사용하여 소형react 응용 프로그램을 구축하는 방법을 중점적으로 소개할 것입니다. Apollo Client는graphql 클라이언트 라이브러리로 모든 주요 전방javascript 프레임워크에 사용할 수 있으며, Apollo 서버는 백엔드를 구축하는 데 사용할 수 있습니다.현재 이 강좌의 모든 코드는 사용할 수 있습니다 on Github.그러면 간단한 응용 프로그램을 구축하기 시작합시다.
    현재 이 프레젠테이션은 간단한 응용 프로그램을 구축하는 데 중점을 두고 전방의 Apollo 클라이언트부터 ReactJs와 Apollo 서버를 사용하여 경량급graphQl 백엔드를 구축한다.간단한 폴더 구조를 설정하는 것부터 시작합시다.이제 이 시작 안내서를 간소화하기 위해 백엔드와 프런트엔드를 같은 폴더에 배치합니다.그럼 시작합시다.


    현재, 폴더 구조를 설정한 후에, 우리는 먼저 백엔드를 구축한 후,react 전단을 구축하여 우리의 데이터를 보여줄 것이다.

    Apollo graphQl로 백엔드 서비스 구축




    이제 초기 폴더를 완성했으니 코드를 작성하는 것부터apollo 서버에 대한 내용을 배우도록 하겠습니다.따라서 index.js 파일에 직접 들어가 기본적인 최소 설정으로 서버를 초기화합니다.
    const {ApolloServer, gql} = require('apollo-server');
    
    const server = new ApolloServer({
      typeDefs,
      resolvers,
    });
    
    server.listen()
        .then(({url}) => {
          console.log(`Server ready at ${url}`);
        })
        .catch(err => {console.log(err)})
    
    지금, 우리가 진일보한 토론을 하기 전에, 우리가 지금까지 작성한 12줄 코드를 분석하고, 우리가 무엇을 사용하고 있는지 봅시다.현재 우리가 본 typeDefsresolvers를 제외하고는 대부분의 코드는 매우 간단하다.그렇다면 typeDefsresolvers가 도대체 무엇인지 먼저 탐구하자.
    모든graphQl 서버는 클라이언트가 접근할 수 있는 데이터와 모델을 통해 완성할 수 있는 데이터를 정의해야 합니다. 이 모델들은 저희 typeDefs 파일에 저장됩니다.현재, 이 모드는 세 개의 루트 조작이 있을 수 있다.이 세 가지 작업은 Query, Mutationsubscription 입니다.이 모든 것은 그 특정한 목적이 있다.Query 데이터베이스에 이미 존재하는 데이터를 가져오는 데 사용되며, Mutation 모든 데이터를 만들거나 업데이트하는 데 사용되며, Subscriptiongraphql 서버에서 생성된 이벤트를 탐지하는 데 사용된다.구독은 게시와 구독 원어를 사용하여 구독을 알리는 이벤트를 생성하는 데 의존합니다.
    현재, 우리는 이미 Query, Mutation, Subscription의 기본 소개를 완성했다.이와 유사하게 resolver는 본질적으로 하나의 함수나 방법으로 모델 중의 필드를 위해 일부 값을 해석한다.그들은 모든 작업을 수행하여 데이터를 얻고 데이터를 만들며 업무 논리를 실행하여 클라이언트가 요구하는 필드를 해결한다.그것들을 결합시켜graphql 서버를 만드는 방법을 보여 줍니다.
    이제 예시 프로그램을 계속합시다.저는 개인적으로 제 resolverstypeDefs 를 분리하는 것을 더 좋아하기 때문에 resolverstypeDefs 을 위한 파일을 만듭니다.

    파일을 만든 후에 새로운 폴더 구조를 살펴보고 typeDefs 를 사용할 수 있습니다. typeDefs 본질적으로 클라이언트와 유사한 인터페이스이기 때문에 클라이언트는 이 인터페이스에 따라 서버에서 데이터를 요청할 수 있습니다.첫 번째 typeDefs 부터 시작합니다.

    현재 앞에서 말한 바와 같이 typeDefs 클라이언트가 우리의 백엔드 서비스에 연결하고 데이터를 요청하는 방식이다.그럼 어떻게 정의하는지 봅시다.
    const {gql} = require('apollo-server');
    
    
    const typeDefs = gql`
            type Query {
                sayHello: String
            }
    
    `
    
    module.exports = typeDefs
    
    현재, 위의 예시에서 우리는 간단한 Query 을 정의했다. 이것은 우리가 백엔드에서 데이터를 얻는 데 도움을 주었다. 우리의 예시에서, 그것은 sayHello 조회 자체가 정의한 String 유형을 되돌려준다.이름 조회가 자체 성명성을 가지도록 하기만 하면 된다.여기에서 우리의 sayHello 명칭은 그것이 무엇을 할 것인지를 명확하게 나타낸다.현재, 우리는 이미 Query 을 정의했고, 우리는 이 조회 정의 typeDefs 함수를 겨냥해야 한다. 이 조회는 실제 해석을 하거나 값을 계산한다.graphQl의 방식은 매 resolver 명칭을 매 typeDefs 함수 명칭에 비추는 것이다.그래서 우리의 예에서, 우리는 반드시 같은 이름으로 해석기를 정의해야 한다.그럼 우리도 이렇게 하자.
    const resolvers = {
      Query: {
        sayHello: () => 'hello random person',
      },
    };
    
    module.exports = resolvers
    
    여기서 우리는 resolver에서 sayHello 함수를 정의했고, 우리의 예시Query에서 함수는 특정 값으로 해석되었다.hello random person 함수의 반환 형식만 확인하십시오. resolver 그렇지 않으면 쿼리가 반환됩니다 typeDefs.이제 nulltypeDefs 파일을 만들었기 때문에 resolvers 파일을 조금만 변경하면 시작할 수 있습니다.우리는 index.jsresolvers 파일을 인덱스로 가져오기만 하면 됩니다.js 파일을 이용합니다.
    const {ApolloServer} = require('apollo-server');
    const typeDefs = require('./typeDefs')
    const resolvers = require('./resolvers')
    const server = new ApolloServer({
      typeDefs,
      resolvers,
    });
    
    server.listen()
        .then(({url}) => {
          console.log(`Server ready at ${url}`);
          ``
        })
        .catch(err => {console.log(err)})
    
    이제 소개를 마쳤기 때문에graphQl로 CRUD 작업을 할 수 있는 간단한 대기사항 목록을 구축합니다.현재, 우리는 일부 데이터베이스를 사용할 생각은 없다. 우리는 백엔드 서비스에서 typeDefs 대상의 형식으로 가짜 데이터베이스를 가지고 있으며, 우리는 그것을 조종하여 CRUD 조작을 실행할 수 있다.가짜 JSON 파일을 만듭니다.

    const DAILY_TASKS = [
      {
        task: "Make Coffee",
        completed: false,
        id: 1
      },
      {
        task: "Learn GraphQl",
        completed: false,
        id: 2
      },
      {
        task: "Learn GoLang",
        completed: false,
        id: 3
      },
      {
        task: "Learn NodeJs",
        completed: false,
        id: 4
      },
      {
        task: "Learn GraphQl",
        completed: false,
        id: 5
      }
    ];
    
    module.exports = DAILY_TASKS;
    
    
    현재, 우리는 가짜 JSON 파일의 데이터를 업데이트, 창설, 삭제하기 위해 3개의 변이가 있고, 상호작용과 데이터 얻기에 사용되는 조회도 1개가 있을 것이다.
    이제 백엔드 서비스에서 데이터를 얻는 첫 번째 json 를 만듭니다.우리는 그것을 Query 라고 부른다.
    const { gql } = require("apollo-server");
    
    const typeDefs = gql`
      type Tasks {
        task: String
        id: ID
        completed: Boolean
      }
      type Query {
        fetchTasks: Tasks
      }
    `;
    
    module.exports = typeDefs;
    
    
    여기에서 가져오기 작업fetchTasks을 정의했습니다. 복귀 유형은 Query 입니다.이제 새로 추가된 검색을 위해 해상도 함수를 작성합시다.
    const DAILY_TASKS = require("./fake_data");
    const resolvers = {
      Query: {
        fetchTasks: () => DAILY_TASKS[0]
      }
    };
    
    module.exports = resolvers;
    
    
    여기서, 우리의 조회는 시종일관 첫 번째 임무로 돌아갈 것이다.이 동작을 업데이트하기 전에 서버를 실행합시다.



    지금, 우리가 네비게이션http://localhost:4000/을 할 때, 우리는 이 GUI를 보았다.이것은graphql놀이터라고 불리는데, 우리는 이곳에서 조회를 실행할 수 있다.여기서 첫 번째Tasks를 운행합시다.

    현재, 우리의 첫 번째 조회를 실행한 후에, 우리는 우리의 결과를 보았다. 그것은 우리의 백엔드에서 데이터를 얻었고, 우리는 위조 JSON 파일에 이 데이터를 가지고 있었다.현재, 우리는 함수에 논리를 추가하고, 클라이언트에서 온 필터로 데이터를 받아들인다.
    const { gql } = require("apollo-server");
    
    const typeDefs = gql`
      type Tasks {
        task: String
        id: ID
        completed: Boolean
      }
    
      input fetchTaskFilter {
        id: ID!
      }
    
      input addTaskInput {
        name: String!
        completed: Boolean!
      }
    
      input updateTaskInput {
        id: ID!
        name: String
        completed: Boolean
      }
    
      type Query {
        fetchTask(filter: fetchTaskFilter): Tasks
        fetchTasks: [Tasks]
      }
    
      type Mutation {
        addTask(input: addTaskInput): Tasks
        updateTask(input: updateTaskInput): Tasks
      }
    `;
    
    module.exports = typeDefs;
    
    
    현재 위의 예에서 우리는 데이터와 상호작용하는 변이와 조회를 정의했다.현재 우리가 본 새로운 사물은 데이터 형식 앞에 있는 Query 표시이다. 이것은 이 필드가 강제적이어서 백엔드에서 조회나 변이를 실행할 수 없다는 것을 의미한다.이제 우리가 데이터와 상호작용할 수 있도록 해상도에 논리를 추가합시다.우리의 해상도 파일의 모든 해상도 함수는 4개의 함수 파라미터를 수신하고, 거의 모든graphql 서버는 어떤 형식으로 해상도에서 이 4개의 함수 파라미터를 수신한다.

  • 루트 - 이전/상위 유형의 결과입니다.

  • args - 클라이언트가 필드에 제공하는 매개 변수입니다.예를 들어 우리!에서 우리typeDefs가 있기 때문에 이 예에서args는 addTask(input:addTaskInput)가 될 것이다.

  • 컨텍스트 - 모든 해석기에 제공되는 가변 객체입니다.이것은 기본적으로 신분 검증, 권한 수여 상태와 조회를 분석할 때 고려해야 할 기타 내용을 포함한다.모든 중간부품을 적용하기 위해 {input:{name:"some name",completed:false}} 대상에 접근할 수 있으며, 상하문을 통해 이 정보를 해상도에 제공할 수 있습니다.

  • 정보 - 질의와 관련된 필드별 정보.이 매개 변수는 고급 상황에서만 사용되지만, 필드 이름, 루트에서 필드까지의 경로 등 조회 실행 상태에 대한 정보를 포함합니다.
  • 여기에서 우리는 주로 ARG를 주목하여 우리의 고객이나 운동장에서 보내는 필드를 방문할 것이다.
    const DAILY_TASKS = require("./fake_data");
    const resolvers = {
      Query: {
        fetchTask: (parent, args, context, info) => {
          return DAILY_TASKS[args.input.id];
        },
        fetchTasks: (parent, args, context, info) => {
          return DAILY_TASKS;
        }
      },
      Mutation: {
        addTask: (parent, args, context, info) => {
          const {
            input: { name, completed }
          } = args;
          const nextId = DAILY_TASKS[DAILY_TASKS.length - 1].id + 1;
          const newTask = {
            task: name,
            completed: completed,
            id: nextId
          };
          DAILY_TASKS.push(newTask);
          return newTask;
        },
        updateTask: (parent, args, context, info) => {
          const {
            input: { id, name, completed }
          } = args;
          const updateTask = DAILY_TASKS.filter(task => {
            return task.id == id;
          });
          if (name) {
            updateTask[0].task = task;
          }
          if (completed) {
            updateTask[0].completed = completed;
          }
          DAILY_TASKS.push(updateTask);
          return updateTask[0];
        }
      }
    };
    
    module.exports = resolvers;
    
    
    현재, 우리는 가짜 데이터베이스와 상호작용하기 위해 간단한 논리를 방금 추가했다.이제 운동장을 통해 어떻게 상호작용하는지 봅시다.

    지금 우리는 이곳에서 모든 돌변과 조회를 보았다.이제 돌변과 조회를 실행해서 그것이 유효한지 봅시다.

    우리는 이미 최소한의 설정으로 서버의 구축을 완성했다.본고에서 우리는 React와 Apollo 클라이언트를 사용하여 우리의 전단 클라이언트를 구축하고 우리가 방금 구축한 API를 이용할 것이다.

    좋은 웹페이지 즐겨찾기