moleculer-api
English
English
  • moleculer-api
  • Quick Start
    • Get Started
    • Configurations
    • Quick Examples
      • REST
        • REST Endpoints
        • REST File Upload with streaming
      • GraphQL
        • GraphQL Resolver with DataLoader
        • GraphQL type extension and reference
      • WebSocket
        • WebSocket Video Broadcasting
        • WebSocket Video Server/Client
        • WebSocket Chat Server/Client
      • Authentication
        • Parse OIDC/OAuth2 context
      • Authorization
        • Access Control with Auth token scopes
        • Access Control with Auth token claims
        • Access Control with IP address
  • API Gateway
    • Overview
    • Service Broker
      • Connenctor
      • Delegator
    • Schema Registry
      • Branch, Version, Integration
      • Protocol Plugin
      • Policy Plugin
      • API Handler
      • API Document Generation
      • Health Check
    • API Server
      • Application
        • Component
          • HTTP
          • WebSocket
        • Context Factory
          • Auth
          • Cookie
          • Correlation ID
          • IP Address
          • Locale
          • Request
          • User-Agent
      • Middleware
        • Error
        • Logging
        • Body Parser
        • Helmet
        • CORS
        • Serve Static
      • HTTP
      • HTTPS
  • Service API Schema
    • Overview
    • Branch
    • Protocol Plugin
      • REST
      • GraphQL
      • WebSocket
    • Policy Plugin
      • Scope
      • Filter
  • Development
    • Overview
    • Service Broker Delegator
      • Manipulating HTTP Response
      • Streaming Request/Response
      • Bidirectional Streaming
    • Schema Registry
      • Protocol Plugin
      • Policy Plugin
    • API Server
      • Application Component
      • Application Context Factory
      • Middleware
  • Miscellaneous
    • Project Roadmap
    • CHANGELOG
    • FAQ
    • Contributors
    • Supporters
  • Github
  • moleculer-iam
Powered by GitBook
On this page

Was this helpful?

Export as PDF
  1. Service API Schema
  2. Protocol Plugin

GraphQL

B. GraphQL

GraphQL API 맵핑에는 call, publish, subscribe, map 커넥터를 이용 할 수 있습니다.

TypeDefs

    GraphQL: {
      typeDefs: `
        """Soccer Player"""
        type Player implements Node {
          id: ID!
          email: String!
          name: String!
          photoURL: String
          position: String
          """A team player belongs to"""
          team: Team
        }

        extend type Query {
          """Current Player"""
          viewer: Player
          player(id: ID!): Player
        }

        extend type Subscription {
          playerMessage: String!
          playerUpdated: Player
        }
      `,

GraphQL 프로토콜에서 typeDefs 속성에 서비스에 필요한 정의(scalar를 제외한 타입, 인터페이스, 열거형 등 모든 형태)을 추가하거나 기존 타입(API Gateway에서 제공하는 기본 타입과 분산 서비스에서 제공한 타입들)을 확장 할 수 있습니다.

Resolvers

      resolvers: {

이하 리졸버에 각 타입들의 필드를 call, publish, subscribe, map 커넥터에 맵핑합니다.

        Player: {

리졸버가 할당되지 않은 필드들은 source 객체에서 동일한 이름의 속성으로부터 주입됩니다.

Call

          team: {
            call: {
              action: "team.get",
              params: {
                id: "@source.teamId",
              },
            },
          },

GraphQL API의 Query 및 Mutation 타입의 필드들에는 publish 및 call 또는 map 커넥터를 이용 할 수 있습니다. params 맵핑에는 @source, @args, @context, @info를 이용 할 수 있습니다.

Map

          position: `({ source, args, context, info }) => source.position.toUpperCase()`,
`

GraphQL 프로토콜에서 map 커넥터 (Inline JavaScript Function String)는 간략하게 field: { map: <FN_STRING> } 대신에 field: <FN_STRING> 방식으로 작성 할 수 있습니다.

          // be noted that special field __isTypeOf got only three arguments
          __isTypeOf: `({ source, context, info }) => return source.someSpecialFieldForThisType != null`,

          // be noted that special field __resolveType got only three arguments
          __resolveType: `
            ({ source, context, info }) => {
              if (source.someSpecialFieldForThisType != null) {
                return "TypeA";
              } else {
                return "TypeB";
              }
            }
          `,
        },

위처럼 Union, Interface 구현 타입을 해석하기 위한 특수 필드에도 Inline JavaScript Function String를 사용합니다.

Batched Call (DataLoader)

        Query: {
          viewer: {
            call: {
              action: "player.get",
              params: {
                id: "@context.user.player.id[]",
              },
            },
          },
          player: {
            call: {
              action: "player.get",
              params: {
                id: "@args.id[]",
              },
            },
          },
        },

위처럼 인증 정보를 포함한 @context나 GraphQL 필드 인자인 @args를 활용해 동일한 액션을 서로 다른 방식으로 맵핑 할 수 있습니다.

한 컨텍스트에서 여러번 호출되는 액션에 배칭을 지원하면 응답 속도를 획기적으로 높힐 수 있습니다. 배칭을 활성화하기 위해서는 call 커넥터의 batchedParams 필드에 배치 처리가 가능한 필드의 이름을 작성하고, 연결된 서비스 액션이 배열로 들어오는 인자 묶음을 처리 할 수 있도록 합니다.

query {
  viewer {
    id
    email
  }
  one: player(id: 1) {
    id
    email
  }
  two: player(id: 2) {
    id
    email
  }
  three: player(id: 3) {
    id
    email
  }
}

위와 같은 GraphQL 요청은 player.get 액션을 { id: [context.user.player.id, 1, 2, 3], ...(other common params) } 페이로드와 함께 한번만 호출하게 됩니다. 연결된 액션이 [{ ... }, { ... }, { ... }, { ... }] 묶음으로 응답을 주면 각 필드에 해당하는 응답이 할당됩니다.

만약 id: 3인 플레이어가 없는 경우 배치 요청을 처리하는 과정에서 에러를 발생시켜 제어 흐름을 멈추는 대신에, 에러를 발생키지않고 배치 응답에 포함시키고 나머지 제어 흐름을 마무리합니다. [{ ... }, { ... }, { ... }, { message: "...", isBatchError: true, ... }] 처럼 isBatchError: true 속성을 갖는 에러 객체를 응답에 포함합니다.

Subscribe

        Subscription: {
          playerMessage: {
            subscribe: {
              events: ["player.message"],
            },
          },

GraphQL API의 Subscription 타입의 필드에서는 subscribe 커넥터를 사용 할 수 있습니다. params 맵핑에는 마찬가지로 @source, @args, @context, @info를 이용 할 수 있습니다. @source에 이벤트 객체가 맵핑됩니다.

@source 객체는 { event, payload }로 구성됩니다. Broker에 따라 기타 속성이 추가 될 수 있습니다.

          playerMessage: {
            subscribe: {
              events: ["player.message"],
              map: `({ source, args, context, info }) => source.payload.message`,
            },
          },
        },
      },
    },

subscribe 커넥터에서는 위처럼 수신된 이벤트 페이로드를 다시 map 커넥터로 변환 할 수 있습니다. subscribe 커넥터 안에서 map 커넥터가 사용되지 않는 경우 이벤트 객체 전체(source)를 반환합니다.

PreviousRESTNextWebSocket

Last updated 4 years ago

Was this helpful?

또한 call 메소드는 GraphQL 요청에서 발생하기 쉬운 N+1 쿼리를 방지하기 위해 요청을 배치로 처리 할 수 있도록 설계되었습니다. (ref. )

Dataloader