[]
js-collaboration-ot의 미들웨어 메커니즘은 서버 측 OT(Operational Transformation) 처리 흐름에서 권한 검증이나 로깅과 같은 로직을 가로채고 커스터마이즈할 수 있도록 해줍니다. 이 문서는 미들웨어의 생명주기, 등록 방법, 그리고 실용적인 예제를 포함하여 미들웨어 사용 방법을 설명합니다.
미들웨어는 DocumentServices의 핵심 확장 기능으로, 연산(op)과 스냅샷(snapshot) 처리 단계에서 사용자 정의 로직을 추가하는 데 사용됩니다.
목적:
연산 흐름을 가로채고 검증
컨텍스트를 수정하거나 처리를 중단
적용 시나리오: 사용자 인증, 데이터 검증, 로깅, 성능 모니터링 등
훅(hook)과의 차이점: 미들웨어는 흐름을 중단하고 오류를 반환할 수 있지만, 훅은 이벤트를 수신하기만 합니다.
미들웨어는 OT 처리 흐름의 여러 단계를 포괄하며, 각 단계는 특정 액션에 대응됩니다. 개발자는 원하는 단계에 선택적으로 개입할 수 있습니다. 아래는 지원되는 미들웨어 액션과 트리거 시점입니다.
액션 | 설명 |
|---|---|
| 서버가 클라이언트 메시지를 수신할 때 트리거되며, 초기 검증이나 로깅에 사용됩니다. |
| 연산( |
| 연산이 스냅샷에 적용되기 직전에 트리거되며, 이 시점의 스냅샷은 아직 이전 상태입니다. |
| 연산이 데이터베이스에 커밋되기 직전에 트리거되며, 연산이 변환된 이후 최종 검증에 사용됩니다. |
| 연산이 데이터베이스에 성공적으로 기록된 후 트리거되며, 후속 처리나 알림에 사용됩니다. |
| 데이터베이스에서 하나 이상의 스냅샷을 로드할 때(예: |
| 데이터베이스에서 연산을 로드할 때 트리거되며, 연산 읽기를 거부할 수 있습니다. |
| 문서가 클라이언트로 오류가 아닌 응답을 보내기 직전에 트리거됩니다. |
미들웨어는 context와 next 파라미터를 받는 비동기 함수입니다.
context: 현재 액션에 대한 컨텍스트 정보(예: connection, request)를 포함합니다.
next: 실행을 계속하기 위한 함수로, 오류를 전달해 흐름을 중단할 수 있습니다.
await next(): 이후 미들웨어 또는 처리 로직을 계속 실행합니다.
await next(error): 흐름을 중단하고 오류를 반환합니다.
docService.use('submit', async (context, next) => {
const user = context.connection.tags.get('user');
if (user.role === 'editor') {
console.log('Submitting operation:', context.request.op);
await next(); // 계속
} else {
await next('No permission'); // 중단
}
});미들웨어는 DocumentServices의 use 메서드를 사용해 등록합니다.
import { DocumentServices } from '@mescius/js-collaboration-ot';
const docService = new DocumentServices();
docService.use('receive', async (context, next) => {
console.log('Message received:', context.request);
await next();
});같은 액션에 대해 여러 미들웨어가 등록된 경우, 등록된 순서대로 실행됩니다.
어떤 미들웨어가 next(error)를 호출하면 이후 미들웨어는 실행되지 않습니다.
docService.use('submit', async (context, next) => {
console.log('Middleware 1');
await next();
});
docService.use('submit', async (context, next) => {
console.log('Middleware 2');
await next();
});
docService.use('submit', async (context, next) => {
console.log('Middleware 3');
await next();
});
// 출력:
// Middleware 1
// Middleware 2
// Middleware 3docService.use('submit', async (context, next) => {
console.log('Middleware 1');
await next();
});
docService.use('submit', async (context, next) => {
console.log('Middleware 2');
await next('Test error');
});
docService.use('submit', async (context, next) => {
console.log('Middleware 3'); // 실행되지 않음
await next();
});
// 출력:
// Middleware 1
// Middleware 2
// 클라이언트로 오류 반환, 클라이언트 측 오류 이벤트 트리거다음은 일반적인 미들웨어 사용 사례와 구현 예시입니다.
docService.use('submit', async (context, next) => {
const user = context.connection.tags.get('user');
if (user.role === 'editor') {
console.log('Submitting operation:', context.request.op);
await next(); // 계속
} else {
await next('No permission'); // 중단
}
});docService.use('afterWrite', async (context, next) => {
console.log('Operation written to database:', context.request.op);
await next();
});미들웨어는 js-collaboration-ot의 서버 측에서 강력한 흐름 제어 기능을 제공합니다.
생명주기의 다양한 단계에 미들웨어를 등록함으로써 검증, 로깅 등 여러 기능을 구현할 수 있습니다.