Apollo-link-rest: λ‚˜λ¨Έμ§€ μ„œλ²„ μš”μ²­μ„ λŒ€κΈ°μ—΄μ— λ„£λŠ” μš°μ•„ν•œ 방법? μ΅œλŒ€ λ™μ‹œμ„±, μ‹œκ°„ 거리, 쑰절 πŸš™βŸ·πŸš•βŸ·πŸš— ?

에 λ§Œλ“  2019λ…„ 01μ›” 20일  Β·  7μ½”λ©˜νŠΈ  Β·  좜처: apollographql/apollo-link-rest

λ‚˜λŠ” 무료 제3자 νœ΄μ‹ API에 λŒ€ν•œ ν˜ΈμΆœμ„ κ΅¬μ„±ν•˜κΈ° μœ„ν•΄ apollo-link-restλ₯Ό μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. 쒋은 ν™œμš© 사둀라고 μƒκ°ν•©λ‹ˆλ‹€.

κ·ΈλŸ¬λ‚˜ 우리 λͺ¨λ‘ μ•Œκ³  μžˆλ“―μ΄ 제3자 APIλŠ” _μš”μ²­ λ™μ‹œμ„± 및 연속적인 API μš”μ²­ κ°„μ˜ μ΅œμ†Œ μ•ˆμ „ 격차와 κ΄€λ ¨ν•˜μ—¬ _respect둜 μ²˜λ¦¬λ˜μ–΄μ•Ό ν•©λ‹ˆλ‹€. 즉, 맀 100ms보닀 더 자주 μ„œλ²„λ₯Ό 곡격

ν΄λ‘œκ°€ 톡화λ₯Ό μΈμˆ˜ν•˜λ©΄μ„œ μ‹œκ°„μ΄ 지남에 따라 톡화 λ₯Ό @export μ§€μ‹œλ¬Έμ„ μ‚¬μš©ν•©λ‹ˆλ‹€.

_ν•œ λ²ˆμ— 두 톡_ πŸš€πŸš€

const QUERY = gql`
  query RestData($email: String!) {
    # 1) Query for user πŸš€
    users @rest(path: '/users/email?{args.email}', method: 'GET', type: 'User') {
      id @export(as: "id")
      firstName
      lastName
      # 2) Sub query for friends fires immediately as well πŸš€
      friends @rest(path: '/friends/{exportVariables.id}', type: '[User]') {
        firstName
        lastName
      }
    }
  }
`;

n+1 쿼리 문제 (즉, 각 μ œν’ˆ μ„€λͺ…보닀 λͺ¨λ“  μ œν’ˆ κ°€μ Έμ˜€κΈ°) μ™„ν™”ν•˜κΈ° μœ„ν•΄ μ„œλ²„ 429 였λ₯˜(μ„œλ²„μ˜ 속도 μ œν•œμœΌλ‘œ μΈν•œ μ‹€νŒ¨)에 λŒ€ν•œ μ•ˆμ „λ§μ„ κ°€μ§ˆ 수 있기λ₯Ό λ°”λžλ‹ˆλ‹€.

_μ§€κΈˆ ν•˜λŠ” 일: λž˜ν•‘ fetch_

const restProviders = new RestLink({
  endpoints: {
    mySlowEndpoint: baseUrl
  },
  customFetch: (...args) =>
    new Promise((resolve, reject) => {
      // πŸš™βŸ·πŸš•βŸ·πŸš— Implementing my queue logic to fire of fetches
        resolve(fetch(...args));
      // when enough time has elapsed. πŸš™βŸ·πŸš•βŸ·πŸš— 
    })
})

μ§€κΈˆμ€ κ°€μ Έμ˜€κΈ° ν”„λ‘œμ„ΈμŠ€λ₯Ό μ‚¬μš©μž 지정 λŒ€κΈ°μ—΄ λ…Όλ¦¬λ‘œ λž˜ν•‘ν•˜κ³  μžˆμ§€λ§Œ 이것을 톡합할 수 μžˆλŠ” "더 μš°μ•„ν•œ 방법"이 μžˆμŠ΅λ‹ˆκΉŒ? λ§Žμ€ μ‚¬λžŒλ“€μ΄ 쿼리λ₯Ό μ¦‰μ‹œ μ‹€νŒ¨ν•˜μ§€ μ•Šκ³  λ‚˜κ°€λŠ” λ‘œλ“œλ₯Ό μ œμ–΄ν•˜λŠ” ​​데 관심이 μžˆμ„ 것이라고 ν™•μ‹ ν•©λ‹ˆλ‹€.

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

Googleμ—μ„œ λ“€μ–΄μ˜€λŠ” λ‹€λ₯Έ μ‚¬λžŒλ“€μ„ μœ„ν•΄ μ§€κΈˆ ν•˜λŠ” 일을 μΆ”κ°€ν•΄μ•Ό ν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€. μ§€κΈˆμ€ p-throttle ( repo )λ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.

// (...)
import pThrottle from "p-throttle";

const restProviders = new RestLink({
  endpoints: {
    mySlowEndpoint: baseUrl
  },
  // Throttle fetches to max 1 concurrent request πŸš€ and
  //  min. delay of 0.5 seconds πŸš™βŸ·πŸš•βŸ·πŸš— .
  customFetch: pThrottle( (...args) => {
    return fetch(...args);
  }, 1, 500)
})

// (...)

λͺ¨λ“  7 λŒ“κΈ€

Googleμ—μ„œ λ“€μ–΄μ˜€λŠ” λ‹€λ₯Έ μ‚¬λžŒλ“€μ„ μœ„ν•΄ μ§€κΈˆ ν•˜λŠ” 일을 μΆ”κ°€ν•΄μ•Ό ν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€. μ§€κΈˆμ€ p-throttle ( repo )λ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.

// (...)
import pThrottle from "p-throttle";

const restProviders = new RestLink({
  endpoints: {
    mySlowEndpoint: baseUrl
  },
  // Throttle fetches to max 1 concurrent request πŸš€ and
  //  min. delay of 0.5 seconds πŸš™βŸ·πŸš•βŸ·πŸš— .
  customFetch: pThrottle( (...args) => {
    return fetch(...args);
  }, 1, 500)
})

// (...)

@D1no customFetch λ₯Ό μ œμ•ˆν•˜λ €κ³  ν–ˆλŠ”λ° 이미 ν•˜μ…¨κ΅°μš”!

이것이 Apollo-link-rest의 직접 ꡬ성 κ°€λŠ₯ν•œ κΈ°λŠ₯인지 ν™•μ‹€ν•˜μ§€ μ•Šμ§€λ§Œ λ¬Έμ„œμ— 이와 같은 μŠ€λ‹ˆνŽ«μ„ ν¬ν•¨ν•˜λŠ” 것을 μ§€μ›ν•©λ‹ˆλ‹€.

이 정보λ₯Ό customFetch둜 ν•  수 μžˆλŠ” 일의 예둜 λ¬Έμ„œμ—μ„œ 쒋은 곳을 μ•Œλ €μ€„ 수 μžˆμŠ΅λ‹ˆκΉŒ? κ·Έ μͺ½μ΄ λ§žλŠ” κ±° κ°™μ•„μš”; 이와 같은 ꡬ성 κ°€λŠ₯성을 apollo-link-rest에 λ˜μ§€λ©΄ 그닀지 μš°μ•„ν•˜μ§€ μ•Šμ€ κ°€μ Έμ˜€κΈ° 방법둠이 κ²°ν•©λ©λ‹ˆλ‹€.

PRμ—μ„œ λ‚˜λŠ” μ΄ˆλ³΄μžκ°€ 읽을 수 μžˆλŠ” 보닀 μΈμœ„μ μΈ 예λ₯Ό μœ„ν•΄ p-queueλ₯Ό κ±·μ–΄μ°¨κ² μŠ΅λ‹ˆλ‹€. GraphQL의 κ΄€λ¬Έ μ•½λ¬Όλ‘œ apollo-link-restλ₯Ό μ§„μ§€ν•˜κ²Œ μ‚¬μš©ν•˜λŠ” μ‚¬λžŒμ€ μ–΄λŠ μ‹œμ μ—μ„œ _λ™μ‹œμ„±/λ””λ°”μš΄μ‹± 관리가 ν•„μš”ν•  κ²ƒμž…λ‹ˆλ‹€.

@D1no , μ—¬κΈ° μ—μ„œ λ¬Έμ„œλ₯Ό 찾을 수 Complete options μœ„μ˜ Options 제λͺ©μ— μžˆμ–΄μ•Ό ν•œλ‹€κ³  μ œμ•ˆν•©λ‹ˆλ‹€.

@tombartonλ‹˜ κ°μ‚¬ν•©λ‹ˆλ‹€. 문제λ₯Ό λ‹€μ‹œ μžμ„Ένžˆ μ‚΄νŽ΄λ³΄λ©΄ μ–΄μ¨Œλ“  κ°€μ Έμ˜€κΈ° ν˜ΈμΆœμ— λŒ€ν•΄ κ°„λ‹¨ν•œ μŠ€λ‘œν‹€ μ˜΅μ…˜μ„ κ°€μ§ˆ 수 μžˆλŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€.

μ›λž˜ μ»€ν”Œλ§ 페치라고 λ§ν–ˆμ§€λ§Œ μ‹€μ œλ‘œλŠ” 사싀이 μ•„λ‹™λ‹ˆλ‹€. μ—¬κΈ°μ—μ„œ λ§Œμ—°ν•˜κ³  μžˆλŠ” (μž„μ˜μ˜) κ°€μ Έμ˜€κΈ° 방법둠에 λŒ€ν•œ ν˜ΈμΆœμž…λ‹ˆλ‹€. apollo-link-rest λ§Ήλͺ©μ μœΌλ‘œ / μ—΄λ§ν•˜λŠ” 싀행을 길듀일 수 있으렀면 μœ„μ—μ„œ λ³Έ 것과 같은 κ°„λ‹¨ν•œ λ™μ‹œμ„± 및 ms μ œν•œ μ˜΅μ…˜μ΄ κ²°κ΅­ κ·Έλ ‡κ²Œ λ‚˜μœ 생각이 아닐 수 μžˆμŠ΅λ‹ˆλ‹€.

const restProviders = new RestLink({
  endpoints: {
    mySlowEndpoint: baseUrl
  },
  maxConcurrency: 2 // Max Concurrency πŸš€πŸš€
  minThrottle: 500 // Handling Rate Limit in ms πŸš™βŸ·πŸš•βŸ·πŸš— 
})

및/λ˜λŠ” μΏΌλ¦¬μ—μ„œ 지정할 수 있음

const QUERY = gql`
  query RestData($email: String!) {
    users @rest(path: '/users/email?{args.email}', method: 'GET', type: 'User') {
      id @export(as: "id")
      firstName
      lastName
      # NEW:       β€₯ πŸš™βŸ·πŸš•     β€₯ πŸš€πŸš€
      friends @rest(throttle: 500, concurrency: 2, path: '/friends/{exportVariables.id}', type: '[User]') {
        firstName
        lastName
      }
    }
  }
`;

κ²°κ΅­, κ°€μ Έμ˜€κΈ° 방법둠이 호좜 λΉˆλ„λ₯Ό 관리해야 ν•˜λŠ” μ΄μœ λŠ” λ¬΄μ—‡μž…λ‹ˆκΉŒ? 그것에 λŒ€ν•΄ 쑰금 μƒκ°ν•˜κ² μŠ΅λ‹ˆλ‹€. μ–΄μ¨Œλ“  customFetch λŠ” 빈 μš”μ²­(μ‚¬λžŒλ“€μ΄ μ •λ§λ‘œ ν•„μš”ν•œ 경우 ν˜„λͺ…ν•œ 결정을 내릴 수 μžˆλ„λ‘)뿐만 μ•„λ‹ˆλΌ ν˜„μž¬ 쿼리에 λŒ€ν•œ 일뢀 정보λ₯Ό 전달받아야 ν•©λ‹ˆλ‹€.

μœ μ§€ κ΄€λ¦¬μž/직원 (@fbartho) 쀑 ν•œ λͺ…이 끼어듀 수 μžˆμŠ΅λ‹ˆκΉŒ? κ·Έ μž₯점이 μΈμ •λœλ‹€λ©΄ PR에 μ‹œκ°„μ„ ν• μ• ν•˜κ³  μ‹ΆμŠ΅λ‹ˆλ‹€.

@D1no μ†”μ§νžˆ λ¬Έμ„œμ— ν¬ν•¨ν•˜μžλŠ” μ œμ•ˆμ΄ λ§ˆμŒμ— λ“€μ—ˆμŠ΅λ‹ˆλ‹€. -- νμž‰μ€ 우리 νšŒμ‚¬ μ•±μ—μ„œ μš°λ¦¬κ°€ μ›ν–ˆλ˜ 방식과 λ°˜λŒ€μž…λ‹ˆλ‹€. (예λ₯Ό λ“€μ–΄ 쀑볡 μ œκ±°λŠ” λ‚΄κ°€ κ΅¬μΆ•ν•œ κ²ƒμž…λ‹ˆλ‹€.)

λ³„λ„λ‘œ μ—”λ“œν¬μΈνŠΈκ°€ μ™„μ „νžˆ λ‹€λ₯Ό 수 μžˆμœΌλ―€λ‘œ "maxConcurrency/minThrottle"을 κΈ€λ‘œλ²Œ 문제둜 μ„€μ •ν•˜λŠ” 것을 μ£Όμ €ν•©λ‹ˆλ‹€.

ApolloLinkRestλŠ” "Apollo에 물건을 μ—°κ²°ν•˜λŠ” 것"에 κ΄€ν•œ κ²ƒμž…λ‹ˆλ‹€. μ—¬λŸ¬λΆ„μ΄ μ„€λͺ…ν•œ μ΄λŸ¬ν•œ λ¬Έμ œλŠ” μ‚¬μš©μž 지정 κ°€μ Έμ˜€κΈ°λΌκ³ λ„ ν•˜λŠ” λ„€νŠΈμ›Œν¬ 계측에 μžˆμ–΄μ•Ό ν•˜λŠ” κ²ƒμ²˜λŸΌ λŠκ»΄μ§‘λ‹ˆλ‹€. -- λ˜ν•œ, λͺ¨λ“  쿼리 κ²½λ‘œμ— λŒ€ν•΄ μ΄λŸ¬ν•œ 값을 μ‚¬μš©μž μ •μ˜ν•  κ°€λŠ₯성이 거의 μ—†μœΌλ―€λ‘œ GraphQL에 섀정을 ν¬ν•¨ν•˜λŠ” 것이 μ‹œλ„λŸ½κ²Œ λ³΄μž…λ‹ˆλ‹€.

μ’‹μŠ΅λ‹ˆλ‹€. λ¨Όμ € λ¬Έμ„œμ— μΆ”κ°€ 사항을 ν™λ³΄ν•˜κ² μŠ΅λ‹ˆλ‹€. κ·Έ μœ„μ— 크림을 λ°”λ₯΄κΈ° 전에 λ¨Όμ € customFetch λ°”λ‹₯에 κΉ”μ•„μ•Ό ν•©λ‹ˆλ‹€.

이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰