본문 바로가기

배움의 즐거움/프로그래밍

(17) Graphql-ruby - 멀티플렉스

반응형



Multiplex


일부 클라이언트는 한번에 여러개의 쿼리를 보낼 수도 있을 것이다.(예를 들어,  Apollo Client’s query batching) 이러한 쿼리는 Schema#multiplex 를 이용하여 동시에 실행할 수 있다. 

멀티플렉스는 자신만의 context,analyzers 그리고 instrumentation을 가질 수 있다.


Concurrent Execution


쿼리를 동시에 실행하기 위해서는 를 사용하여 쿼리 옵션을 만들어야 한다. 예를 들어:

# 각 쿼리의 context 를 준비
context = {
  current_user: current_user,
}

# 쿼리 옵션 준비
queries = [
  {
   query: "query Query1 { someField }",
   variables: {},
   operation_name: 'Query1',
   context: context,
 },
 {
   query: "query Query2 ($num: Int){ plusOne(num: $num) }",
   variables: { num: 3 },
   operation_name: 'Query2',
   context: context,
 }
]


그리고 Schema#multiplex 에 패스한다.

results = MySchema.multiplex(queries)

results 는 queries에 있는 모든 쿼리에 대한 결과를 포함할 것이다.


Apollo Query Batching


Apollo 는 _json params 에 batch 변수를 보내는데, 스키마가 bached와 non-bached 쿼리 모두를 핸들링할 수 있는지 확인해야 한다(?). 아래는 디폴트 Apollo batch를 핸들링 할 수 있또록 다시 씌여진 GraphqlController 의 예시이다.

def execute
  context = {}

  # Apollo sends the params in a _json variable when batching is enabled
  # see the Apollo Documentation about query batching: http://dev.apollodata.com/core/network.html#query-batching
  result = if params[:_json]
    queries = params[:_json].map do |param|
      {
        query: param[:query],
        operation_name: param[:operationName],
        variables: ensure_hash(param[:variables]),
        context: context
      }
    end
    MySchema.multiplex(queries)
  else
    MySchema.execute(
      params[:query],
      operation_name: params[:operationName],
      variables: ensure_hash(params[:variables]),
      context: context
    )
  end

  render json: result
end


Validation and Error Handling


각 쿼리는 각각 유효성이 검사되고 분석된다. results 는 성공 결과와 실패 결과를 모두 포함할 수 있다.


Multiplex-Level Context


 context: 에 해쉬를 제공함으로써 Execution::Multiplex#context 에 값을 추가할 수 있다.

MySchema.multiplex(queries, context: { current_user: current_user })

이 것은  multiplex.context[:current_user] 로써 instrumentation 에서도 사용 가능하다.(아래를 보자)


Multiplex-Level Analysis


멀티플렉스 analyzer를 추가함으로써 멀티플렉스에 있는 모든 쿼리를 분석할 수 있다.

class MySchema < GraphQL::Schema do
  # ...
  multiplex_analyzer(MyAnalyzer)
end

API 는 query analyzers 와 동일하지만 다음과 같은 것을 고려해야 한다. 

  • initial_value 는 멀티플렉스(쿼리가 아닌) 시작 부분에서 호출된다.
  • final 멀티플렉스(쿼리가 아닌) 끝 부분에서 호출된다.
  • call(...) 각 쿼리의 각 노드에서 호출되는데, 멀티플렉스의 모든 노드를 차례로 방문하게 된다.

Multiplex analyzers 는 전체 멀티플렉스의 실행을 중지하기 위해 AnalysisError 를 리턴할 수 있다.


Multiplex Instrumentation


multiplex instrumentation 으로 각 멀티플렉스 실행에 후크를 추가할 수 있다.

instrumenter은 반드시 .before_multiplex(multiplex)와 after_multiplex(multiplex)를 구현해야 한다. 그리고 이는 에 마운트 될 수 있다. 사용가능한 메서드가 어떤 것들이 있는지 보기 위해 Execution::Multiplex 를 보자.

# 멀티플렉스 실행에 쿼리가 몇개나 있는지 볼 수 있다.
module MultiplexCounter
  def self.before_multiplex(multiplex)
    Rails.logger.info("Multiplex size: #{multiplex.queries.length}")
  end

  def self.after_multiplex(multiplex)
  end
end

# ...

class MySchema < GraphQL::Schema
  # ...
  instrument(:multiplex, MultiplexCounter)
end

MultiplexCounter.before_multiplex 는 각 멀티플렉스 이전에 불리고 .after_multiplex는 이후에 불리고 있다.


* 해당 글은 번역기 돌리다가 크롬 번역기 말도 안되는 해석에 지친 본인이 나중에 참고할 의도로 대충대충 발로 해석한 것이니 참고용으로만 사용하시길 바랍니다.

* 출처: http://graphql-ruby.org/queries/multiplex.html


반응형