Apollo-Server를 사용하여 OMVC에 반응


이 강좌에서 저는 Apollo 서버와 Apollo client 3을 사용하여 간단한 TodoMVC를 구축하는 방법을 공유할 것입니다.우리는 React-TodoMVC 응용 프로그램을 구축하여 apollo 서버와 클라이언트의 기본 지식을 소개할 것이다.
이것은 튜토리얼의 첫 번째 부분입니다. - Apollo 서버를 사용하여 백엔드를 구축합니다.
  • 1. Apollo-Server
  • 를 사용하여 OMVC에 반응
  • 2. Apollo-Customer(WIP)
  • 와 함께 OMVC에 대한 대응
  • 3. 아폴로 테스트(WIP)
  • 를 통해 OMVC에 반응
  • 4. 아폴로와 함께 DOMVC 대응 - 배포(WIP)
  • 선결 조건


    React 또는 Apollo/Graphql 초보자라면 다음 링크를 먼저 찾아 요점을 얻으십시오.
  • 반응
  • 그래픽 QL
    https://graphql.org/
  • 아폴로
  • 일이 많지 않으니 우리 시작합시다!

    설치


    프로젝트 폴더를 만들려면 다음과 같이 하십시오.
    mkdir todomvc-apollo-server
    cd todomvc-apollo-server
    
    
    먼저 package.json 프로젝트에 필요한 라이브러리를 만듭니다.
    {
      "name": "todomvc-apollo-server",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
        "start": "nodemon --exec babel-node src/index.js"
      },
      "keywords": [],
      "author": "",
      "license": "ISC",
      "devDependencies": {
        "@babel/cli": "^7.10.5",
        "@babel/core": "^7.11.4",
        "@babel/node": "^7.10.5",
        "@babel/preset-env": "^7.11.0",
        "nodemon": "^2.0.4"
      },
      "dependencies": {
        "apollo-server": "^2.17.0",
        "graphql": "^15.3.0"
      }
    }
    

    설치 종속성:


    npm i
    

    바베타 배치


    새로운 javascript 기능을 사용하려면 다음과 같은 내용을 포함하는 .babelrc 를 만들어서 babel을 설정해야 합니다.
    {
      "presets": ["@babel/preset-env"]
    }
    
    npm-check-updates를 사용하여 최신 버전으로 업데이트할 수 있습니다.

    실시


    다음 정거장에서는 기본적인 apollo 서버를 구현합니다. 이 서버는 업무 목록을 되돌려주는api를 포함합니다.

    1 - 첫 번째 Graphql 질의


    구조


    모델은 우리가 유형, 조회, 변이, 구독을 정의하는 곳이다.우리의 강좌에서, 우리는 TODO 유형과 todos 조회가 있다.이것은 클라이언트로서 내가 TODO를 조회할 때 나는 TODO 수조를 응답으로 얻고 싶다는 것을 의미한다.느낌표는 이 값이null이 될 수 없음을 나타냅니다. 즉, 해석 프로그램은 이 형식이null로 되돌아와서는 안 됩니다.더 많은 정보 읽기: https://graphql.org/learn/schema/#lists-and-non-null.
    다음을 사용하여 작성typeDefs.js.
    const { gql } = require("apollo-server");
    
    export const typeDefs = gql`
      type Query {
        todos: [TODO!]!
      }
      type TODO {
        id: ID!
        text: String!
        completed: Boolean!
      }
    `;
    

    해상도


    다음을 사용하여 작성resolvers.js.
    간단하게 말하자면, 해상도는 우리가 조회/변이/구독을 위해 무엇을 해야 하는지를 정의한다.이 예에서 우리는 단지 TODO 수조로 돌아가 조회를 진행할 뿐이다todos.
    export const resolvers = {
      Query: {
        todos: () => [
          {
            id: "0",
            text: "Buy milk",
            completed: false,
          },
          {
            id: "1",
            text: "Sing a song",
            completed: true,
          },
        ],
      },
    };
    

    지수회사 명


    생성index.js, 거기서 아폴로 서버를 시작합니다.
    import { ApolloServer } from "apollo-server";
    import { typeDefs } from "./typeDefs";
    import { resolvers } from "./resolvers";
    
    const server = new ApolloServer({ typeDefs, resolvers });
    
    server.listen().then(({ url }) => {
      console.log(`🚀  Server ready at ${url}`);
    });
    
    이제 우리는 기본적인 아폴로 서버를 완성했다.npm start를 운행하고 http://localhost:4000를 열면 아폴로 운동장이 운행하는 것을 볼 수 있을 거예요!🚀
    아래의 조회를 해 보세요. 아폴로가 오른쪽에서 우리의 업무 목록으로 돌아오는 것을 볼 수 있을 거예요!🐸
    query todos {
      todos {
        id
        text
        completed
      }
    }
    
    

    You can find code we had so far in here.

    https://github.com/bluedusk/todomvc-apollo/tree/server/1-basic-apollo-server


    2-돌연변이


    아날로그 데이터 소스


    서버에 변이를 추가하기 전에기본 todo CRUD 함수를 제공하는 아날로그 데이터 원본을 만들고 datasource.js as blow를 만들어야 합니다.
    /**
     * A mock datasource providing todo CRUD functionalities
     */
    export class Todos {
      constructor() {
        this.todos = [
          {
            id: "0",
            text: "Buy milk",
            completed: false,
          },
          {
            id: "1",
            text: "Sing a song",
            completed: true,
          },
        ];
      }
    
      getTodos() {
        return this.todos;
      }
    
      setTodos(todos) {
        this.todos = todos;
      }
    
      addTodo(todoText) {
        const todo = {
          id: String(this.getTodos().length + 1),
          text: todoText,
          completed: false,
        };
        this.todos.push(todo);
        return todo;
      }
    
      deleteTodo(id) {
        const todo = this.todos.find((todo) => todo.id === id);
        if (todo) {
          this.todos = this.todos.filter((todo) => todo.id !== id);
        }
        return todo;
      }
    
      updateTodoById(id, text) {
        let result;
        this.todos.forEach((todo) => {
          if (todo.id === id) {
            // update text or completed
            if (text) {
              todo.text = text;
            } else {
              todo.completed = !todo.completed;
            }
            result = todo;
          }
        });
    
        return result;
      }
      deleteAll() {
        this.todos = [];
      }
      deleteCompleted() {
        this.todos = [...this.todos].filter(({ completed }) => !completed);
      }
      completeAll() {
        this.todos = [...this.todos].map((todo) => {
          return {
            ...todo,
            completed: true,
          };
        });
      }
    }
    

    typeDefs 업데이트


    다음 돌연변이 추가typeDefs.js
      type Mutation {
        addTodo(text: String!): TODO!
        updateTodo(id: ID!, text: String): TODO!
        deleteTodo(id: ID!): TODO
        completeAll: Boolean
        deleteCompleted: Boolean
      }
    

    해상도 업데이트


    다음 업데이트로 교체합니다resolvers.js.해석기 함수에서 매개 변수와 상하문을 어떻게 가져오는지 주의하십시오.
    export const resolvers = {
      Query: {
        todos: (parent, args, { Todos }) => {
          return Todos.getTodos();
        },
      },
      Mutation: {
        addTodo: (parent, { text }, { Todos }) => {
          const result = Todos.addTodo(text);
          return result;
        },
        deleteTodo: (parent, { id }, { Todos }) => {
          const result = Todos.deleteTodo(id);
          return result;
        },
        updateTodo: (parent, { id, text }, { Todos }) => {
          const result = Todos.updateTodoById(id, text);
          return result;
        },
        deleteCompleted: (_, __, { Todos }) => {
          Todos.deleteCompleted();
          return true;
        },
        completeAll: (_, __, { Todos }) => {
          Todos.completeAll();
          return true;
        },
      },
    };
    

    색인을 업데이트합니다.회사 명


    다음 업데이트로 교체합니다index.js.이전 섹션의 모든 해석기 방법에서 사용할 수 있도록 TODO를 컨텍스트에 주입합니다.우리의 예시에서 우리는 todos 대상이 여러 검색에서 공유되기를 원하기 때문에 상하문은 하나의 대상이 아니라 하나의 대상이기 때문에 모든 요청에 트리거되지 않습니다.실제로 우리는 새로운 상하문이 필요한 모든 요청에 대해 상하문을 하나의 함수로 설정할 수 있기를 희망할 수 있다. ()=>{/****/}

    More on context: https://www.apollographql.com/docs/apollo-server/data/resolvers/#the-context-argument


    import { ApolloServer } from "apollo-server";
    import { typeDefs } from "./typeDefs";
    import { resolvers } from "./resolvers";
    import { Todos } from "./datasource";
    
    const server = new ApolloServer({
      typeDefs,
      resolvers,
      // context: Where we "inject" our fake datasource
      context: {
        Todos: new Todos(),
      },
      // plugins(optional): A small plugin to print log when server receives request
      // More on plugins: https://www.apollographql.com/docs/apollo-server/integrations/plugins/
      plugins: [
        {
          requestDidStart(requestContext) {
            console.log(
              `[${new Date().toISOString()}] - Graphql operationName:  ${
                requestContext.request.operationName
              }`
            );
          },
        },
      ],
      // capture errors
      formatError: (err) => {
        console.log(err);
      },
    });
    
    // The `listen` method launches a web server at localhost:4000.
    server.listen().then(({ url }) => {
      console.log(`🚀  Server ready at ${url}`);
    });
    
    운동장에서 스팸 정보를 검색하여 컨트롤러에 보내는 것을 피하기 위해 운동장 설정을 blow로 변경하십시오.
      "schema.polling.enable": false,
    
    그렇습니다!서버가 실행 중인지 확인하고 환매 중 검사schema.test.graphql하면 운동장에서 변이를 시도할 수 있습니다!

    You can find code we had so far in here.

    https://github.com/bluedusk/todomvc-apollo/tree/server/2-mutations


    구독


    우리의 다음 임무는graphql 구독을 사용하는 것입니다.
    우리가 끊임없이 클라이언트로부터 돌아가며 업데이트를 받지 않고 서버를 통해 전송하기를 원할 때 구독은 매우 편리하다.(참고로, Apollo가 동적 폴링을 지원하는 경우 폴링은 동적 시작/중지를 허용하고 폴링 간격을 설정할 수 있는 몇 가지 용례에 충분할 수 있습니다.https://www.apollographql.com/docs/react/data/queries/#usequery-api

    Unlike queries, subscriptions maintain an active connection to your GraphQL server (most commonly via WebSocket). This enables your server to push updates to the subscription's result over time.
    https://www.apollographql.com/docs/react/data/subscriptions/


    구조


    제출 형식을 typeDefs.js에 추가하면 조회와 변이와 마찬가지로 구독은 다른 루트 형식입니다.
      type Subscription {
        todos: [TODO!]!
      }
    

    분해기

    resolvers.js를 다음으로 대체합니다.
    import { PubSub } from "apollo-server-express";
    
    const pubsub = new PubSub();
    const TODO_CHANGED = "TODO_CHANGED";
    
    const doPublish = (todos) => {
      pubsub.publish(TODO_CHANGED, { todos });
    };
    
    export const resolvers = {
      Query: {
        todos: (parent, args, { Todos }) => {
          return Todos.getTodos();
        },
      },
      Mutation: {
        addTodo: (parent, { text }, { Todos }) => {
          const result = Todos.addTodo(text);
          doPublish(Todos.getTodos());
          return result;
        },
        deleteTodo: (parent, { id }, { Todos }) => {
          const result = Todos.deleteTodo(id);
          doPublish(Todos.getTodos());
          return result;
        },
        updateTodo: (parent, { id, text }, { Todos }) => {
          const result = Todos.updateTodoById(id, text);
          doPublish(Todos.getTodos());
          return result;
        },
        deleteCompleted: (_, __, { Todos }) => {
          Todos.deleteCompleted();
          doPublish(Todos.getTodos());
          return true;
        },
        completeAll: (_, __, { Todos }) => {
          Todos.completeAll();
          doPublish(Todos.getTodos());
          return true;
        },
      },
      Subscription: {
        todos: {
          subscribe: () => {
            return pubsub.asyncIterator([TODO_CHANGED]);
          },
        },
      },
    };
    
    구독 분석기에서 이벤트 탐색 중TODO_CHANGED:
      subscribe: () => {
        return pubsub.asyncIterator([TODO_CHANGED]);
      },
    
    
    돌변에서 이 이벤트를 발표합니다. 예를 들어 todo 추가/삭제/업데이트:
    pubsub.publish(TODO_CHANGED, { todos });
    
    구독 테스트를 위해 우리는 두 개의 놀이터(http://localhost:4000를 열었고 첫 번째 놀이터에서 우리는 구독을 시작했다.
    subscription sub_todos {
      todos {
        id
        text
        completed
      }
    }
    
    너는 그것이 듣기 시작하는 것을 볼 수 있다.두 번째 운동장에서 우리는 처리해야 할 사항을 추가했다.
    mutation addTodo {
      addTodo(text: "another todo") {
        id
        text
        completed
      }
    }
    
    
    addTodo 이후 첫 번째 운동장에서 이벤트를 받고 todo 목록을 업데이트할 수 있습니다🌟

    You can find code we had so far in here.

    https://github.com/bluedusk/todomvc-apollo/tree/server/3-subscriptions


    중지


    이것은 아폴로 서버의 본 강좌의 일부분이다.다음 부분에서, 우리는 apollo 클라이언트를 사용하여 todoMvcreact 클라이언트를 구축할 것입니다.읽어주셔서 감사합니다!

    좋은 웹페이지 즐겨찾기