Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Integration Process
병합 규칙은 다음과 같습니다.
discover
discover 발생 즉시 병합 요청이 생성됩니다.
프로토콜 플러그인을 따라 스키마 포맷에 대한 검증을 거칩니다.
포맷 에러는 병합 요청 메세지 리스트에 포함됩니다.
접근 제어를 우회하는 엔드포인트에 대한 경고가 병합 요청 메세지 리스트에 포합됩니다.
검증 성공시 병합 요청이 큐에 삽입되면서 특정 시간(2초를 기본값) 동안 debounce 후 순차적으로 처리됩니다.
큐에서 특정 서비스에 대한 병합 요청이 다수인 경우 마지막 요소만 유효합니다.
프로토콜 플러그인에서 integrationDependencyResolver가 구현된 경우 (eg. GraphQL) 큐 안에서 처리 순서가 조정 될 수 있습니다.
검증 실패시 report 단계로 건너 뜁니다.
hash
서비스 API 스키마에서 branch, description, deprecated등의 메타 정보를 제외한 스키마 객체 전체를 MD5 해싱하여 고유한 버전 해시를 생성합니다.
게이트웨이에 버전이 존재하지 않는 경우에는 스키마를 업데이트하기로 합니다.
서비스 노드의 연결이 끊긴 경우는 연관된 스키마의 노드풀에서 노드를 삭제합니다.
이 때 연관된 스키마들에서 노드풀이 빈 스키마들을 제거하기로 합니다.
update
master 브랜치의 스키마는 경우에는 모든 브랜치에 병합이 시도됩니다.
이 때 master 외의 브랜치에서 스키마의 서비스명이 중복되는 경우 병합하지 않습니다. 기존 스키마의 우선 순위가 높습니다.
이외의 브랜치에 병합하는 경우에는 주어진 브랜치에만 병합이 시도됩니다.
프로토콜 플러그인을 따라 각 프로토콜별 핸들러를 생성합니다.
병합에 성공하면 생성된 Gateway API 스키마 버전에 latest 태그 및 8 글자의 숏 해시(eg. abcdefgh)가 태그로 부착됩니다.
옵션이 활성화된 경우 브랜치별 API Catalog를 업데이트합니다.
옵션이 활성화된 경우 브랜치별 Service Catalog를 업데이트합니다.
report
병합 요청의 메세지 리스트를 기반으로 디버그 메세지를 생성합니다.
병합 요청의 출처 노드로 디버그 메세지를 report합니다.
Branch Strategy Diagram
브랜치간 병합 전략을 표로 도식하면 다음과 같습니다.
표에서 a@v1는 a 서비스 스키마 중 v1 버전을 의미합니다.
이벤트/브랜치
master
dongwook
비고
initial schema
(empty)
N/A
a added to master
a@v1
N/A
a updated to master
a@v2
N/A
b added to dongwook
a@v2
a@v2 b@v1
새로운 b 서비스를 dongwook 브랜치로 분기해서 작업; 충돌하지 않는 스키마들은 복제되지 않고 참조됩니다.
a updated to master
a@v3
a@v3 b@v1
master 브랜치의 업데이트는 모든 브랜치로 전파됩니다.
a updated to dongwook
a@v3
a@v4 b@v1
master 이외의 브랜치의 업데이트는 자기 브랜치로만 전파됩니다.
a updated to master
a@v3-2
a@v4 b@v1
충돌하는 경우 자기 브랜치 스키마의 우선 순위가 높습니다.
c added to master
a@v3-2 c@v1
a@v5 b@v1 c@v1
master 브랜치의 업데이트는 모든 브랜치로 전파됩니다.
b added to master
a@v3-2 b@v1 c@v1
a@v5 b@v1 c@v1
개발된 b 서비스를 dongwook 브랜치에서 master 브랜치로 변경
a updated to master
a@v5 b@v1 c@v1
a@v5 b@v1 c@v1
수정된 a 서비스를 dongwook 브랜치에서 master 브랜치로 변경
dongwook branch removed
a@v5 b@v1 c@v1
N/A
Routing Rule
Gateway 웹 서버는 [/~BRANCH[@TAG]]/<ENDPOINT>의 규칙대로 API 엔드포인트를 라우트합니다. 첫번째 경로 조각을 브랜치(master를 기본값으로)로 두번째 경로 조각을 태그(latest를 기본값으로)로 이하 경로를 API 엔드포인트로 해석합니다.
라우트 예시
간략
브랜치 포함
태그 포함
GET /players/1
GET /~master/players/1
GET /~master@latest/players/1
-
-
GET /~master@h4g3f2e1/players/1
-
GET /~dongwook/players/1
GET /~dongwook@latest/players/1
-
-
GET /~dongwook@a4b3c2d1/players/1
POST /graphql
POST /~master/graphql
GET /~master@latest/graphql
-
POST /~dongwook/graphql
GET /~dongwook@latest/graphql
-
GET /~ws-dev/chat
GET /~ws-dev@latest/chat
테이블의 각 행은 동일한 버전의 핸들러로 연결됩니다.
브랜치 이름 규칙
영문 소문자 및 숫자, -, _만 허용됩니다.
기존 스키마 엔드포인트나 플러그인의 base 경로와 중복될 수 없습니다.
태그 이름 규칙
영문 소문자 및 숫자로만 구성됩니다.
플러그인은 서비스 API 스키마의 포맷과 기능을 확장하는데 쓰입니다. 플러그인은 위임된 스키마에 대한 검증, 해석, 작동 방식을 정의하고 구현합니다.
각 프로토콜 플러그인은 해당 프로토콜 스키마의 양식을 정의하고, 스키마 병합, 요청 프록시, 의존성 파악, 서버 확장 핸들러 등을 구현합니다.
각 접근 제어 플러그인은 해당 접근 제어 스키마의 양식을 정의하고, call, publish, subscribe 커넥터의 정책을 해석하고 접근 제어를 판단하는 핸들러를 구현합니다.
프토토콜 플러그인별 스키마 양식은 API Schema 섹션을 참조하십시오. 이 섹션에서는 기본 플러그인의 구동 방식을 개괄적으로 설명합니다.
REST 프로토콜은 분산 서비스에 대한 call, publish 커넥터를 특정 엔드포인트에 맵핑합니다. HTTP 요청의 Paylo,ad는 미들웨어를 통해 파싱되어 params 커넥터를 통해 변환되어 call, publish 커넥터로 전달됩니다.
엔드포인트가 중복되는 경우 병합을 발생시킨 출처 노드로 디버그 메세지가 report되며 병합에 실패합니다.
API Catalog를 통해서 엔드포인트 별 적용된 정책 및 커넥터와 그 파라미터에 대한 설명을 제공합니다.
TODO: $headers, $status, $body field for REST response
GraphQL 프로토콜은 분산 서비스에 대한 call 및 publish, subscribe 커넥터를 특정 타입의 필드에 맵핑합니다. HTTP 요청의 Payload는 미들웨어를 통해 파싱되어 params 커넥터를 통해 변환되어 call, publish, subscribe, map 커넥터로 전달됩니다.
GraphQL 스키마 생성에 실패하는 경우 병합을 발생시킨 출처 노드로 디버그 메세지가 report되며 병합에 실패합니다.
API Catalog를 통해서 각 GraphQL Type 별 적용된 정책 및 커넥터와 그 파라미터에 대한 설명을 제공합니다.
서비스 API 스키마를 통해서 GraphQL Custom Scalar 정의를 추가 할 수 없습니다. Gateway 생성시 플러그인 옵션을 통해 Scalar 정의를 추가하거나 오버라이드 할 수 있습니다. 기본적으로 DateTime, Date, Time, JSON가 포함되어있습니다.
TODO: WIP
Server Extension은 웹 서버를 생성 및 확장하는데 쓰입니다. 서버 생성 옵션을 통해 제어 할 수 있습니다.
HTTP
HTTP Extension은 HTTP 프로토콜을 지원하도록 웹 서버를 생성합니다. 기본적으로 활성화됩니다.
HTTP/2
HTTP/2 Extension은 HTTP/2 프로토콜을 지원하도록 웹 서버를 생성합니다.
TLS
TLS Extension은 HTTPS 요청을 처리 할 수 있도록 웹 서버를 생성합니다.
엔드포인트로의 라우팅 전/후에 미들웨어들이 실행됩니다. 서버 생성 옵션을 통해 제어 할 수 있습니다.
엔드포인트로의 라우팅 전에 수행되는 미들웨어입니다.
Static
Static Middleware는 최초로 수행되는 미들웨어입니다. 활성화시 API Gateway 서비스 노드의 특정 디렉토리에서 애셋 파일들을 서빙합니다.
Body Parser
Body Parser는 application/json, application/x-www-form-url-encoded, multipart/form-data Content Type 요청의 바디를 JavaScript 객체로 해석합니다.
Cookie Parser
Cookie Parser는 Cookie 헤더를 JavaScript 객체로 해석하고 검증합니다.
CORS
CORS 미들웨어는 교차 출처 자원 공유에 대한 접근 제어 정책에 따라 Preflight 요청에 응답합니다.
Helmet
Helmet 미들웨어는 서버에 CSP, HSTS 등 기초적인 보안 요소를 추가합니다.
엔드포인트로의 라우팅 직전에 Context Factory 미들웨어를 통해 요청 컨텍스트를 생성하게 됩니다. Context는 API Handler에 전달되는 인증, Locale, Language, TimeZone 등의 정보를 포함한 객체입니다.
Locale
Locale 컨텍스트는 요청 헤더로부터 Locale, Language, TimeZone 등의 정보를 추출합니다.
Auth
인증 컨텍스트를 활성화하기 위해서는 요청으로부터 서버 생성 옵션을 통해 인증 정보를 생성하는 함수를 구현해야합니다. 예를 들어 Bearer 토큰을 moleculer-iam 피어 모듈을 통해 통해 파싱해 idToken을 획득하거나, 별도의 인증 서버에 전달해 원하는 방식대로 해석 할 수 있습니다.
엔드포인트로에서의 응답 후에 수행되는 미들웨어입니다.
Error
Error 미들웨어는 분산 서비스의 에러를 파악하고 HTTP 상태 코드를 설정하며 표준화된 에러 포맷의 응답을 생성합니다.
ETag
ETag 미들웨어는 GET, HEAD 요청 및 응답(200 OK)에서 If-None-Match 및 ETag 헤더를 활용해 API 클라이언트의 성능을 높힙니다.
Header
Header 미들웨어는 Header Context에 값이 할당된 경우 응답 헤더를 업데이트합니다.
요청이 전처리 미들웨어, 컨텍스트 미들웨어를 통과 한 후에 동적으로 생성된 엔드포인트로 라우팅됩니다. API 핸들러를 통과 한 후 후처리 미들웨어를 지나 요청이 완료됩니다.
동적 핸들러는 Gateway에 생성된 브랜치에 따라 요청을 브랜치 핸들러로 프록시합니다.
브랜치 핸들러는 Gateway에 생성된 해당 브랜치의 태그에 따라 요청을 버전 핸들러로 프록시합니다.
버전 핸들러는 Gateway API 스키마에 따라 커넥터 및 프로토콜 플러그인을 조합해 생성한 핸들러로 요청을 프록시합니다.
Dynamic Handler
동적 핸들러는 웹 서버의 모든 base 경로를 관리하며, 미들웨어 및 플러그인, 엔드포인트 간의 경로 충돌을 방지합니다. 동적 핸들러는 조건에 따라 브랜치 핸들러 및 버전 핸들러를 생성 및 삭제하며 동적으로 라우트 테이블을 구성합니다.
동적 핸들러는 클라이언트의 요청에 따라 미들웨어를 수행하고, 브랜치 핸들러로 요청을 프록시합니다.
Branch Handler
브랜치 핸들러는 태그에 따라 버전 핸들러로 요청을 프록시합니다.
이 브랜치 핸들러들은 아래의 규칙에 따라 삭제됩니다.
master 브랜치를 제외하고, 60분 이상 실행되지 않는 브랜치 핸들러는 삭제됩니다.
Version Handler
서비스 API 스키마의 병합이 일어날 때마다 새로운 버전의 Gateway API 스키마가 생성됩니다. 병합에 성공한 Gateway API 스키마는 latest 및 숏해시로 태그됩니다. 그리고 업데이트된 엔드포인트별로 스키마, 프로토콜 플러그인, 커넥터를 연결해 각 핸들러를 생성합니다. 업데이트되지 않은 스키마의 핸들러는 가능한 재참조됩니다.
이 버전 핸들러들은 아래의 규칙에 따라 삭제됩니다.
10개를 초과(기본값)하는 버전이 존재한는 경우 오래된 순으로 버전 핸들러가 삭제됩니다.
Non-Persistence
API 스키마의 브랜치 및 태그 기능은 버전 관리(/v1, /v2 같은)가 아닌 분산 환경에서의 개발 편의를 위해 개발되었습니다.
주의사항
Gateway에는 Persistence Layer가 존재하지 않습니다.
Gateway 재시작시 브랜치, 버전 및 태그 정보가 복원되지 않습니다.
Gateway 노드간에 데이터 동기화 전략이 존재하지 않습니다.
Gateway 노드간에 서비스 API 스키마 병합의 순서가 동일하게 보장되지 않습니다.
하지만 Gateway 재시작 이후 모든 서비스들에 대한 discover가 진행되면서 자연스럽게 각 브랜치의 latest 버전에는 최신 Gateway API 스키마가 복원됩니다. 각 브랜치의 latest 버전의 신뢰성은 보장됩니다.
API Gateway constructor options.
APIGatewayOptions type is a kind of container for all the subordinate components' options.
type APIGatewayOptions = {
brokers: RecursivePartial<ServiceBrokerOptions>[],
schema: RecursivePartial<SchemaRegistryOptions>,
server: RecursivePartial<APIServerOptions>,
logger: LoggerConstructorOptions,
} & RecursivePartial<APIGatewayOwnOptions>;name
default
description
brokers
-
Service Broker constructor options. Can configure multiple brokers for a single gateway. Service Broker discovers remote services and works as a delegator for calling remote service procedures and also deals with central event messages.
schema
-
Schema Registry constructor options. Schema Registry handles the integration of remote service API schema and creates API handlers. Can disable or configure detailed options for each API Schema Plugins like GraphQL, REST and WebSocket, etc.
server
-
API Server constructor options. Can configure API Server update policy, server components (HTTP, WebSocket server) and network interface (HTTP, HTTPS) detailed options, middleware options and request context factory options.
logger
-
Global logger options. Currently logger is supported.
Options for the gateway itself rather inner components.
type APIGatewayOwnOptions = {
skipProcessEventRegistration: boolean;
};name
default
description
skipProcessEventRegistration
false
Set true to not to set default handlers for process interrupt signals like SIGINT.
Service Broker options are consist of common properties and delegator specific properties. The common properties show below.
type ServiceBrokerOptions = {
registry: ServiceRegistryOptions;
batching: BatchingPoolOptions;
function: InlineFunctionOptions;
reporter: ReporterOptions;
log: {
event: boolean;
call: boolean;
},
} & ServiceBrokerDelegatorConstructorOptions;name
default
description
registry
-
Options for the ServiceRegistry which collect remote services, available procedures and event types, etc.
batching
-
Options for batching feature which utilize for concurrent multiple procedure calls.
function
-
Options for inline function (JS function notation string) sandbox.
reporter
-
Options for remote service reporter instance which reports API integration status, error or logging in inline function sandbox, etc.
log.event
true
Enable logging event messages.
log.call
true
Enable logging remote procedure call.
type ServiceRegistryOptions = {
examples: {
processIntervalSeconds: number;
queueLimit: number;
limitPerActions: number;
limitPerEvents: number;
streamNotation: string;
omittedNotation: string;
omittedLimit: number;
redactedNotation: string;
redactedParamNameRegExps: RegExp[];
};
healthCheck: {
intervalSeconds: number;
};
};name
default
description
examples
-
Options for the ServiceRegistry action (remote procedure), event example collecting feature.
examples.processIntervalSeconds
5
Consume example queue for every given intervals.
examples.queueLimit
50
Example queue size.
examples.limitPerActions
10
Maximum number of examples for a single action (remote procedure).
examples.limitPerEvents
10
Maximum number of examples for a single event.
examples.streamNotation
*STREAM*
Replace stream request and response of an example to given string.
examples.omittedNotation
*OMITTED*
Truncate example object's string property and append given suffix for...
examples.omittedLimit
100
The strings longer than given length.
examples.redactedNotation
*REDACTED*
React example object's string property to given string for...
examples.redactedParamNameRegExps
[
/password/i,
/secret/i,
/credential/i,
/key/i,
/token/i,
]
Matched strings with given regular expressions.
healthCheck
-
Options for the ServiceRegistry health check feature.
healthCheck.intervalSeconds
10
Health check for every given intervals.
type BatchingPoolOptions = {
batchingKey: (...args: any[]) => any;
entryKey: (batchingParams: any) => any;
failedEntryCheck: (entry: any) => boolean;
entriesLimit: number;
};name
default
description
batchingKey
(hash function)
A keygen function for the key of same batching arguments. Create hash string with args object by default.
entryKey
(hash function)
A keygen function for the variable params of each batched entries.
failedEntryCheck
entry => entry && entry.batchingError
A function to determine whether each entries are failed or not in a batch response. By default, a remote procedure which supports batching should response { ..., batchingError: true } object for failed entry.
entriesLimit
100
Maximum number of entries for a single batch.
type InlineFunctionOptions = {
util: {[key: string]: any};
};name
default
description
util
{}
Any kind of object which can be accessed as global util variable from inline functions.
type ReporterOptions = {
tableWidthZoomFactor: number;
};name
default
description
tableWidthZoomFactor
1
A reporter sends a report which is consist of raw messages and a string that prints messages as a shape of a table. For that table, set a zoom factor of the width.
Specific options for the Service Broker Delegator. Can choose only one among supported delegators. Currently moleculer delegator is supported.
type ServiceBrokerDelegatorConstructorOptions = {
moleculer?: MoleculerServiceBrokerDelegatorOptions;
[otherDelegatorKey]?: any;
};name
default
description
moleculer
-
Service Broker Delegator options.
moleculer delegator can be configured with moleculer broker own options and few extra options like below.
import * as Moleculer from "moleculer";
type MoleculerServiceBrokerDelegatorOptions = Moleculer.BrokerOptions & {
batchedCallTimeout: (itemCount: number) => number;
streamingCallTimeout: number;
streamingToStringEncoding: "ascii" | "utf8" | "utf-8" | "utf16le" | "ucs2" | "ucs-2" | "base64" | "latin1" | "binary" | "hex";
services: Moleculer.ServiceSchema[];
};name
default
description
batchedCallTimeout
(return 5-60s based on item count)
A function to calculate the timeout options for a batched call.
streamingCallTimeout
3600000 (1 hour)
A timeout options for a streaming call (ms).
streamingToStringEncoding
base64
An encoding which is used to transform streaming data to buffer data. This is for the case that non-root property of payload is a readable stream. Because moleculer service broker can pipe only a single streaming data at once in a single params, a gateway needs to transform non-root streaming data to buffer data before proxy the action call. Try to check your moleculer service broker transporter options and this option for a malformed streaming data issue.
services
[]
Given Moleculer.ServiceSchema[] would be registered on moleculer service broker started. This is for the testing convenience.
Service Registry options are consist of own options for the registry itself and Protocol, Policy, this two type of Plugin constructor options.
type SchemaRegistryOptions = {
maxVersions: number;
maxUnusedSeconds: number;
protocol: ProtocolPluginConstructorOptions,
policy: PolicyPluginConstructorOptions,
};name
default
description
maxVersions
10
Maximum number of old versions for each branches.
maxUnusedSeconds
1800
Maximum unused duration until deleting non-master branches.
protocol
-
A ProtocolPlugin handles mapping Public API to calling internal services' procedure, publishing and subscribing event messages.
policy
-
A PolicyPlugin handles access controls (authorization) while calling internal services' procedure, publishing and subscribing event messages.
type ProtocolPluginConstructorOptions = {
GraphQL: RecursivePartial<GraphQLProtocolPluginOptions> | false;
REST: RecursivePartial<RESTProtocolPluginOptions> | false;
WebSocket: RecursivePartial<WebSocketProtocolPluginOptions> | false;
}export type PolicyPluginConstructorOptions = {
scope: RecursivePartial<ScopePolicyPluginOptions> | false;
filter: RecursivePartial<FilterPolicyPluginOptions> | false;
};