DelegatingHandler란 무엇인가?
ASP.NET Web API에서 메시지 핸들러(Message Handler)는 여러 개의 핸들러가 하나의 체인(chain) 형태로 연결되어 동작합니다. 체인의 첫 번째 핸들러가 HTTP 요청을 받아 일정한 처리를 수행한 뒤 요청을 다음 핸들러에 전달하고, 어느 시점에서 응답이 생성되면 그 응답은 다시 체인을 거슬러 올라가 최종적으로 호출자에게 반환됩니다. 이러한 패턴을 위임 핸들러(Delegating Handler)라고 부릅니다.
커스텀 서버 측 HTTP 메시지 핸들러 만들기
ASP.NET Web API는 기본 제공되는 서버 측 메시지 핸들러 외에도, 개발자가 직접 서버 측 HTTP 메시지 핸들러를 작성할 수 있도록 지원합니다. 커스텀 서버 측 HTTP 메시지 핸들러를 만들려면 System.Net.Http.DelegatingHandler 클래스를 상속받는 새로운 클래스를 정의하고, 그 안에서 SendAsync 메서드를 재정의(override)하면 됩니다.
Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken);이 메서드는 HttpRequestMessage를 입력으로 받아 HttpResponseMessage를 비동기적으로 반환합니다. 일반적인 구현 절차는 다음과 같습니다.
- 요청 메시지(request message)를 처리합니다.
- base.SendAsync를 호출하여 요청을 내부 핸들러(inner handler)로 전달합니다.
- 내부 핸들러가 응답 메시지를 반환합니다. (이 과정은 비동기로 수행됩니다.)
- 응답을 추가로 처리한 뒤 호출자에게 반환합니다.
예제 1: 기본적인 커스텀 메시지 핸들러
다음은 요청과 응답의 흐름을 추적하는 가장 기본적인 형태의 위임 핸들러입니다.
public class CustomMessageHandler : DelegatingHandler{ protected async override Task<HttpResponseMessage> SendAsync( HttpRequestMessage request, CancellationToken cancellationToken){ Debug.WriteLine("CustomMessageHandler processing the request"); // 내부 핸들러 호출 var response = await base.SendAsync(request, cancellationToken); Debug.WriteLine("CustomMessageHandler processing the response"); return response; }}예제 2: 내부 핸들러 건너뛰기
위임 핸들러는 필요에 따라 내부 핸들러를 호출하지 않고 직접 응답을 생성하여 즉시 반환할 수도 있습니다. 이 방식은 특정 조건에서 요청을 컨트롤러까지 전달하지 않고 차단해야 할 때 유용합니다.
public class CustomMessageHandler : DelegatingHandler{ protected override Task<HttpResponseMessage> SendAsync( HttpRequestMessage request, CancellationToken cancellationToken){ // 응답 생성 var response = new HttpResponseMessage(HttpStatusCode.OK){ Content = new StringContent("Skipping the inner handler") }; // TaskCompletionSource는 델리게이트 없이 작업을 생성 var taskCompletion = new TaskCompletionSource<HttpResponseMessage>(); taskCompletion.SetResult(response); return taskCompletion.Task; }}핸들러 등록하기
작성한 커스텀 핸들러를 Web API 파이프라인에 적용하려면 애플리케이션 시작 시 HttpConfiguration 객체에 등록해야 합니다.
config.MessageHandlers.Add(new CustomMessageHandler());주요 활용 사례
DelegatingHandler는 요청과 응답이 파이프라인을 통과하는 지점을 가로챌 수 있기 때문에 다음과 같은 기능을 구현하는 데 널리 활용됩니다.
- API 키 검증, 토큰 기반 인증 등 인증 및 권한 확인
- 요청/응답 로깅 및 모니터링
- CORS 헤더 추가 등 응답 헤더 처리
- 특정 조건에서의 요청 차단 또는 리디렉션