React에서 axios로 Rails API 설치 클릭

기존 Rails 서비스를 완벽하게 React화하는 이유 및 방법의 속편.
안녕하세요.
저는 Rep University 대학 개요 검색 시스템에서 운영하는 슈지켄입니다.
기존 Rails 서비스를 완벽하게 React화하는 이유 및 방법에 React화의 이유와 방법을 적었다.
이번에는 단숨에 구체성을 높여 실복을 많이 말하고,React에서 API를 두드리는 부분의 실복을 쓴다.
GET 때의 Canceler와 POST 때의 config 전환에 공을 들였습니다. 꼭 읽어주세요!
솔직히 JS 초보자가 너무 많은 것 같아서 이상한 점이 있으면 댓글로 남겨주세요.공부 좀 하게 해주세요.

기술을 사용하다


프런트엔드
  • React 16.13.0
  • axios 0.19.2
  • TypeScript
  • 서버측
  • Rails5.1 시스템
  • rack-cors
  • 하고 싶은 일

  • 안내데스크(web.rep-rikkyo.com)에서 웹 API(wwww.rep-rikkyo.com)
  • 두드리기
  • GET, POST, PUT, DELETE 등 각종 방법으로 두드리기
  • 인증 정보를 요청 헤더에 기록
  • Rails 의 대응


    대강 한 차례 설명하다.
    이번에는 기존 라일스만 실행하는 서비스에서 앞부분을 잘라냈기 때문에 라일스는 API 모드가 아니다.
    그곳 설치는 교차 사냥꾼자리 사이의 요청을 가능하게 한다rack-cors gem.
    Gemfile에서 다음을 추가합니다.
    gem 'rack-cors'
    
    config/initializers/cors.rb를 제작하면 다음과 같은 방법으로 https://web.rep-rikkyo.com로부터 요청을 받을 수 있습니다.
    # frozen_string_literal: true
    
    Rails.application.config.middleware.insert_before 0, Rack::Cors do
      allow do
        origins 'https://web.rep-rikkyo.com'
    
        resource '*',
                 headers: :any,
                 methods: %i[get post put patch delete options head],
                 credentials: true,
                 expose: %w[access-token uid client expiry]
      end
    end
    
    이것origins을'어쨌든 먼저*'이런 기사로 만든 경우도 있지만, 어디서 맞아도 너무 무서워서 잘 지목해야 한다.
    또한origins에서 여러 개의 영역을 배열로 전달한다는 보도도 있지만 string만 받아들이기 때문에origins ['https://a.rep-rikkyo.com', 'https://b.rep-rikkyo.com'].map(&:strip)처럼 강제 문자열화하자.
    다른 controller의 API화와protect_from_forgery 등의 설정은 적당한 시간이 필요하다고 생각하지만 필요하지 않다.

    React 측


    드디어 주제.
    API를 두드리는 것은 각양각색의 component에서 시작하기 때문에 추상화는 필수적이다.

    axiosInstance 초기화


    axios에 대한 조사를 통해 알 수 있듯이 axios.create(config)를 통해 axios Instance를 제작할 수 있다.
    대상의 API 필드는 하나이고 모든 HTTP 방법은 같은 config를 통과할 수 있기 때문에 먼저 axios Instance를 초기화하는 함수를 만들었다.
    import axios from 'axios';
    
    const DEFAULT_API_CONFIG: ApiConfig = {
      baseURL: 'https://www.rep-rikkyo.com',
      timeout: 5000,
      mode: 'cors',
      credentials: 'include',
      headers: {
        ContentType: 'application/json',
        Accept: 'application/json',
      },
    };
    
    const newAxiosInstance = () => {
      const instance = axios.create(DEFAULT_API_CONFIG);
    
      instance.interceptors.response.use(
        response => {
          if (process.env.NODE_ENV === 'development') {
            console.log(response); // 便利☆
          }
          return response;
        },
        error => {
          return Promise.reject(error);
        }
      );
    
      return instance;
    };
    

    GET 때리기 함수


    일단 코드부터.
    ★fetch라는 함수 이름이 JS표준fetch와 함께 쓰여서 좋지 않다.
    interface Options {
      cancelToken?: CancelToken;
    }
    
    export const fetch = async (
      path: string,
      query?: Object,
      options?: Options
    ) => {
      const instance = newAxiosInstance(options);
    
      try {
        const response = await instance.get(path, { params: query });
        return response;
      } catch (error) {
        return error.response;
      }
    };
    
    함수 내에는 방금 만든 newAxios Instance 함수만 사용하여 axios의get를 실행합니다.

    첫 번째 매개변수:path


    두드린api를 나타내는 path를 '/api/v1/lessons/100'와 같은 문자열에 건네줍니다.

    두 번째 인자:query


    GET이므로 필요한 매개변수의 Object를 첨부합니다.Rep에서 검색되는 매개변수는 대부분 통과됩니다.

    매개변수 3: options에 대한 CancelToken


    기능을 사용하는 Canceler를 사용하여 요청을 취소할 수 있습니다.
    이것은 요청에서 응답으로 길어질 수 있는 상황에서 유효합니다.
    예를 들어 Rep의 코스 검색에서 Canceler는 다음과 같은 기능을 제공합니다.
  • 필요한 검색 조건으로 API
  • 두드리기
  • 시간이 걸리지 않는 경미한 검색
  • 에 이어
  • 1 취소 요청
  • 2 요청 반영
  • 先のリクエストがキャンセルされた例
    아까 부탁이 취소된 거 알아요.
    그리고 이것을 이용할 수 있도록newAxiosInstance도 다시 써야 한다.
    const newAxiosInstance = (options?: Options) => {
      const config = DEFAULT_API_CONFIG;
      const configWithCancelToken = { ...config, cancelToken: options?.cancelToken }
    
      const instance = axios.create(configWithCancelToken);
      ・・・
    }
    

    Canceler 사용 방법


    간단하게 이전 cancelToken을 변수로 저장하고 두 번째 이후의 요청 전에 cancelTokencancel()이 있었다면.
    import axios, { Canceler } from 'axios';
    
    let CancelToken = axios.CancelToken;
    let cancel: Canceler | null;
    
    const SearchLesson: React.FC = () => {
      const searchLesson = async (query: SearchQuery) => {
        if (cancel) {
          // fetchのcancelerがすでにある場合 = 一度fetchしようとしたが、まだ完了していないときはfetchをキャンセルする
          cancel();
          cancel = null;
        }
        const res = await fetch('/lesson/search', query, {
          cancelToken: new CancelToken(function executor(c) {
            cancel = c;
          }),
        });
        cancel = null;
      };
      ・・・
    }
    

    POST의 함수 두드리기


    기본적으로 GET와 같지만 Rep에서 POST에서 인증 상태를 확인하는 API는 거의 모두 해당한다.
    interface Options {
      isAuth?: boolean; // 追加
      cancelToken?: CancelToken;
    }
    
    export const post = async (
      path: string,
      query?: Object,
      options?: Options
    ) => {
      const instance = newAxiosInstance(options);
    
      try {
        const response = await instance.post(path, query);
        return response;
      } catch (error) {
        return error.response;
      }
    };
    
    isAuth가 Options에 추가되었습니다.
    이 new Axios Instance에 맞춰 수정도 하고.
    매개 변수 options.isAuth와 함께 API config를 전환합니다.
    export const AUTHED_API_CONFIG = (): ApiConfig => {
      return {
        baseURL: 'https://www.rep-rikkyo.com',
        timeout: 5000,
        mode: 'cors',
        credentials: 'include',
        headers: {
          ContentType: 'application/json',
          Accept: 'application/json',
    
          // 認証情報をヘッダーに載っける
          'access-token': authInfo().Token,
          client: authInfo().Client,
          uid: authInfo().Uid,
        },
      }
    };
    
    const newAxiosInstance = (options?: Options) => {
      const isAuth = options ? options.isAuth : false; // 追加
      const config = isAuth ? AUTHED_API_CONFIG() : DEFAULT_API_CONFIG; // 追加
      const configWithCancelToken = { ...config, cancelToken: options?.cancelToken }
    
      const instance = axios.create(configWithCancelToken);
      ・・・
    }
    
    POST를 실행하는 곳은 GET의 Canceller만큼 복잡하지 않기 때문에 사랑을 끊는다.

    최후


    Rails에 rack-cors를 가져와 Axios로 API를 두드렸다.
    GET의 Canceler와 POST 때 config 변환에 조금 공을 들였습니다.
    ● 실제로 글을 많이 읽고 패러디한 부분도 있지만 원본 파일을 찾아도 찾지 못해 미안하다
    단서가 있는 사람은 메시지를 남겨주세요.
    이번에 전선을 많이 넣었어!

    좋은 웹페이지 즐겨찾기