λλ λ¬΄λ£ μ 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)
})
// (...)
@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
λ°λ₯μ κΉμμΌ ν©λλ€.
κ°μ₯ μ μ©ν λκΈ
Googleμμ λ€μ΄μ€λ λ€λ₯Έ μ¬λλ€μ μν΄ μ§κΈ νλ μΌμ μΆκ°ν΄μΌ ν μλ μμ΅λλ€. μ§κΈμ
p-throttle
( repo )λ₯Ό μ¬μ©ν©λλ€.