Appearance
Pipes
Pipe는 Guard를 통과한 IPC 요청의 인자를 변환하거나 검증하는 파이프라인이다. 핸들러가 실행되기 전에 역직렬화, 유효성 검사 등을 수행한다.
파이프라인 흐름
요청 → Guard(canActivate) → Pipe(transform) → Handler → 응답
↓ (실패) ↓ (에러) ↓ (에러)
ExceptionHandler ExceptionHandler ExceptionHandler
↓ ↓ ↓
응답 응답 응답- Guard를 모두 통과한다
- contract에 내장된 schema가 있으면 프레임워크가 먼저 강제한다 (
schema.parse(args[0])) - 글로벌 Pipe를 순서대로 실행한다
- 핸들러별 Pipe(
@UsePipes)를 순서대로 실행한다 - 변환된 인자로 핸들러를 실행한다
Pipe에서 throw하면 ExceptionHandler가 처리한다.
IpcPipe 인터페이스
ts
interface IpcPipe {
transform(args: unknown[], ctx: IpcContext): unknown[] | Promise<unknown[]>;
}| 매개변수 | 타입 | 설명 |
|---|---|---|
args | unknown[] | 핸들러에 전달될 인자 배열 |
ctx | IpcContext | IPC 요청 컨텍스트 (채널, 윈도우 등) |
반환값은 다음 Pipe 또는 핸들러에 전달할 변환된 인자 배열이다.
NOTE
스키마 검증은 Pipe를 직접 만들 필요가 없다 — handle(channel, { schema })로 contract에 내장하면 프레임워크가 모든 파이프보다 먼저 강제한다. Contract 참조. Pipe는 스키마로 표현할 수 없는 변환·검증에 사용한다.
커스텀 Pipe 작성
특정 필드를 검증하는 Pipe 예시:
ts
import type { IpcPipe, IpcContext } from '@repo/electron-ipc';
class CwdPipe implements IpcPipe {
transform(args: unknown[], _ctx: IpcContext) {
const params = args[0];
if (params && typeof params === 'object' && 'cwd' in params) {
const cwd = (params as { cwd: unknown }).cwd;
if (typeof cwd === 'string' && cwd.length > 0) {
validateCwd(cwd);
}
}
return args;
}
}적용 방법
글로벌 Pipe
createApp()의 pipes 배열로 전달한다. 모든 IPC 요청에 적용된다.
ts
createApp({
guards: [new SenderGuard()],
pipes: [new NormalizePipe()],
exceptionHandler: new ErrorHandler(),
modules: [WindowModule, MyModule],
});핸들러별 Pipe
@UsePipes() 데코레이터로 특정 핸들러에만 Pipe를 적용한다. 글로벌 Pipe 이후에 실행된다.
ts
import { Controller, UsePipes } from '@repo/electron-ipc';
@Controller(myContract)
class MyController {
@UsePipes(new CwdPipe())
startSession(params: SessionParams) {
// CwdPipe를 통과한 후 실행된다
return this.service.start(params);
}
listSessions() {
// CwdPipe가 적용되지 않는다
return this.service.list();
}
}실행 순서
글로벌 Pipe → 핸들러별 Pipe 순서로 실행된다. 각 Pipe의 반환값이 다음 Pipe의 입력이 된다.
ts
// contract schema: 있으면 항상 먼저
// 글로벌: [NormalizePipe]
// 핸들러별: [CwdPipe]
// 실행 순서:
// 1. schema.parse(args[0]) → parsedArgs (contract에 schema가 있을 때)
// 2. NormalizePipe.transform(parsedArgs, ctx)
// 3. CwdPipe.transform(..., ctx)
// 4. handler(...)효과
Pipe를 도입하면 핸들러에서 역직렬화와 검증 보일러플레이트가 제거된다:
ts
// Before — 핸들러가 파싱과 검증을 직접 수행
startSession(params: unknown) {
const parsed = SessionSchema.parse(params);
validateCwd(parsed.cwd);
return this.service.start(parsed);
}
// After — 스키마는 contract가 강제하고, 나머지 검증만 Pipe가 처리한다
// contract: handle<[SessionParams], void>('session:start', { schema: SessionSchema })
@UsePipes(new CwdPipe())
startSession(params: SessionParams) {
return this.service.start(params);
}다음 단계
- Guards — Pipe 이전에 실행되는 요청 검증
- Exception Handlers — Pipe에서 발생한 에러 처리
- API Reference — IpcPipe, UsePipes 전체 시그니처