Appearance
Pipes
Pipe는 Guard를 통과한 IPC 요청의 인자를 변환하거나 검증하는 파이프라인이다. 핸들러가 실행되기 전에 역직렬화, 유효성 검사 등을 수행한다.
파이프라인 흐름
요청 → Guard(canActivate) → Pipe(transform) → Handler → 응답
↓ (실패) ↓ (에러) ↓ (에러)
ExceptionHandler ExceptionHandler ExceptionHandler
↓ ↓ ↓
응답 응답 응답- Guard를 모두 통과한다
- 글로벌 Pipe를 순서대로 실행한다
- 핸들러별 Pipe(
@UsePipes)를 순서대로 실행한다 - 변환된 인자로 핸들러를 실행한다
Pipe에서 throw하면 ExceptionHandler가 처리한다.
IpcPipe 인터페이스
ts
interface IpcPipe {
transform(args: unknown[], ctx: IpcContext): unknown[] | Promise<unknown[]>;
}| 매개변수 | 타입 | 설명 |
|---|---|---|
args | unknown[] | 핸들러에 전달될 인자 배열 |
ctx | IpcContext | IPC 요청 컨텍스트 (채널, 윈도우 등) |
반환값은 다음 Pipe 또는 핸들러에 전달할 변환된 인자 배열이다.
커스텀 Pipe 작성
Zod 스키마로 인자를 파싱하는 Pipe 예시:
ts
import type { IpcPipe, IpcContext } from '@repo/electron-ipc';
import type { ZodType } from 'zod';
const SCHEMA_MAP: Record<string, ZodType> = {
'theme:set': ThemeSchema,
'profile:create': CreateProfileSchema,
};
class ZodPipe implements IpcPipe {
transform(args: unknown[], ctx: IpcContext) {
const schema = SCHEMA_MAP[ctx.channel];
if (!schema) return args;
return [schema.parse(args[0])];
}
}특정 필드를 검증하는 Pipe 예시:
ts
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 ZodPipe()],
exceptionHandlers: [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
// 글로벌: [ZodPipe]
// 핸들러별: [CwdPipe]
// 실행 순서:
// 1. ZodPipe.transform(args, ctx) → parsedArgs
// 2. CwdPipe.transform(parsedArgs, ctx) → validatedArgs
// 3. handler(...validatedArgs)효과
Pipe를 도입하면 핸들러에서 역직렬화와 검증 보일러플레이트가 제거된다:
ts
// Before — 핸들러가 파싱과 검증을 직접 수행
startSession(params: unknown) {
const parsed = SessionSchema.parse(params);
validateCwd(parsed.cwd);
return this.service.start(parsed);
}
// After — Pipe가 처리하고, 핸들러는 비즈니스 로직에 집중
@UsePipes(new CwdPipe())
startSession(params: SessionParams) {
return this.service.start(params);
}다음 단계
- Guards — Pipe 이전에 실행되는 요청 검증
- Exception Handlers — Pipe에서 발생한 에러 처리
- API Reference — IpcPipe, UsePipes 전체 시그니처