Apollo 클라이언트를 사용하여 RESTAPI 호출 포장: 직접 작업 방법

애플리케이션이 REST에서 GraphQL API로 마이그레이션할 때 필요한 데이터가 두 API 간에 분할되는 경우가 있습니다.예를 들어, REST API에서 데이터를 가져오면 Redux, MobX 또는 Vuex가 될 수 있는 애플리케이션 전체 상태에 저장됩니다.그러나 새로운 반짝이는 GraphQL API가 생겨서 응답을 저장하는 템플릿 파일을 만들 필요가 없습니다. Apollo 클라이언트가 이 과정을 처리할 것입니다!이것은 두 개의 API가 있다는 것을 의미하는 것입니까? 당신은 낡은 좋은 무료한 해결 방안을 견지하고 Apollo 클라이언트 캐시를 버려야 합니까?하나도 안 그래!
Apollo 패키지 RESTAPI 호출을 사용하여 결과를 Apollo 캐시에 저장할 수 있습니다.만약 대형 응용 프로그램이 있고 많은 응용 프로그램이 있다면, apollo-link-rest 라이브러리를 사용하여 이 점을 실현할 수 있습니다.본고에서 우리는 이 임무를 완성하기 위해 기본적인 DIY 방법을 만들어서 아폴로 해석기의 작업 방식과 응용 프로그램에서 어떻게 영구적으로 사용하는지 잘 이해할 것이다.

우리는 무엇을 건설해야 합니까?


예를 들어 Rick and Morty API에 구축된 Vue 단일 페이지 응용 프로그램을 사용합니다.이 API의 장점은 REST와 GraphQL 단점을 동시에 가지고 있기 때문에 우리는 이를 실험할 수 있다.
어플리케이션에서 RESTAPI만 사용한다고 가정합니다.따라서 전방에 Vuex 저장소가 있습니다. 저희는 Vuex actions에서 axios 조회를 호출하여 API에서 캐릭터와 드라마를 얻습니다.
// Vuex state

state: {
  episodes: [],
  characters: [],
  favoriteCharacters: [],
  isLoading: false,
  error: null
},
// Vuex actions

actions: {
  getEpisodes({ commit }) {
    commit('toggleLoading', true);
    axios
      .get('/episode')
      .then(res => commit('setEpisodes', res.data.results))
      .catch(err => commit('setError', error))
      .finally(() => commit('toggleLoading', false));
  },
  getCharacters({ commit }) {
    commit('toggleLoading', true);
    axios
      .get('/character')
      .then(res => commit('setCharacters', res.data.results))
      .catch(err => commit('setError', err))
      .finally(() => commit('toggleLoading', false));
  },
  addToFavorites({ commit }, character) {
    commit('addToFavorites', character);
  },
  removeFromFavorites({ commit }, characterId) {
    commit('removeFromFavorites', characterId);
  }
}
Vuex 돌연변이를 열거하지 않았습니다. 왜냐하면 매우 직관적이기 때문입니다. - 추출한 문자를 state.characters에 분배합니다.
보시다시피 로드 플래그를 수동으로 처리하고 오류가 발생했을 때 저장해야 합니다.characters 배열의 각 문자는 객체입니다.

이제 백엔드 개발자가 드라마를 얻기 위해 검색을 만들었지만, 여전히 RESTAPI를 통해 캐릭터를 구해야 한다고 상상해 봅시다.그렇다면 우리는 어떻게 대응해야 하는가?

1단계: GraphQL 모드 확장


GraphQL에서 우리가 끝점에서 얻을 수 있는 모든 내용은 유형이 있어야 하고 GraphQL 모드에서 정의해야 한다.일관성을 유지하고 characters을 모드에 추가합니다."근데 어떻게 해요?"구조는 백엔드에서 정의됩니다!"라고 물어볼 수도 있습니다.이것은 사실이지만, 우리도 전방에서 이 모드를 확장할 수 있다!이 과정을 schema stitching이라고 부른다.비록 이 단계는 완전히 선택할 수 있지만, 나는 여전히 실체에 대한 GraphQL 형식의 정의를 항상 건의합니다. 설령 그것이 로컬일지라도.code generation을 사용하여 GraphQL 모드에서 TypeScript 유형과 같은 유형을 만들면 도움이 되며, IDE에서 Apollo plugin을 사용하면 인증 및 자동 완료가 활성화됩니다.
캐릭터를 위한 새로운 유형을 만듭니다.graphql-tag을 사용하여 문자열을 GraphQL 유형으로 해석합니다.
// client.js

import gql from "graphql-tag";

const typeDefs = gql`
  type Character {
    id: ID!
    name: String
    location: String
    image: String
  }
`;
보시다시피 character 대상의 모든 필드를 사용하지 않고 필요한 필드만 사용합니다.
현재 GraphQL Query 쿼리를 사용하여 characters 유형을 확장해야 합니다.
// client.js

import gql from "graphql-tag";

const typeDefs = gql`
  type Character {
    id: ID!
    name: String
    location: String
    image: String
  }
  extend type Query {
    characters: [Character]
  }
`;
이 모드를 GraphQL 끝에서 가져온 모드와 결합하려면 typeDefs을 GraphQL 클라이언트 옵션으로 전달해야 합니다.
// client.js

import { ApolloClient } from "apollo-client";
import { createHttpLink } from "apollo-link-http";
import { InMemoryCache } from "apollo-cache-inmemory";
import gql from "graphql-tag";

const httpLink = createHttpLink({
  uri: "https://rickandmortyapi.com/graphql"
});

const cache = new InMemoryCache();

const typeDefs = gql`
  type Character {
    id: ID!
    name: String
    location: String
    image: String
  }
  extend type Query {
    characters: [Character]
  }
`;

export const apolloClient = new ApolloClient({
  link: httpLink,
  cache,
  typeDefs
});

2단계: 쿼리 및 해상도 작성

@client 명령이 있는 GraphQL 조회를 정의해야 합니다. 문자를 가져오려면 이 명령이 호출됩니다.@client 명령은 Apollo 클라이언트에게 GraphQL 단점에서 이 데이터를 가져오지 말고 로컬 캐시에서 이 데이터를 가져오라고 알려준다.일반적으로, 나는 검색을 .gql 파일에 저장하고, 그것을 가져올 수 있도록 graphql-tag/loader을 웹 설정에 추가합니다.
// characters.query.gql

query Characters {
  characters @client {
    id
    name
    location
    image
  }
}
그런데 문제가 하나 있습니다. 로컬 캐시에 문자가 없습니다!우리는 어떻게 아폴로 고객에게 이 데이터를 어디서 얻을 수 있는지 설명합니까?이를 위해, 우리는 해상도를 작성해야 한다.응용 프로그램에서 문자를 추출하려고 할 때마다 이 해상도를 호출합니다.
해상도 대상을 만들고 characters 조회를 위한 해상도를 정의합니다
// client.js

const resolvers = {
  Query: {
    characters() {
      ...
    }
  }
};
우리는 여기서 무엇을 해야 합니까?알겠습니다. Vuex 액션과 같은 axios 호출을 실행해야 합니다!GraphQL 유형 필드에 응답 필드를 매핑하여 구조를 보다 명확하게 만듭니다.
// client.js

const resolvers = {
  Query: {
    characters() {
      return axios.get("/character").then(res =>
        res.data.results.map(char => ({
          __typename: "Character",
          id: char.id,
          name: char.name,
          location: char.location.name,
          image: char.image
        }))
      );
    }
  }
};
그렇습니다!GraphQL characters 쿼리를 호출하면 Rest API 호출을 실행하고 결과를 반환합니다.추가점: REST API 호출이 진행 중일 때 $apollo.queries.characters.loading 속성이 변경됩니다!또한 이 호출에서 오류가 발생하면아폴로 조회 error 연결이 촉발됩니다.

결론


보시다시피 REST 노드에 있는 API의 일부는 Apollo 클라이언트와 캐시를 사용하지 못하게 합니다.모든 RESTAPI 호출은 Apollo resolver로 봉인할 수 있으며, 그 결과는 Apollo 캐시에 저장되어 이전 과정을 간소화할 수 있다.

좋은 웹페이지 즐겨찾기