Lsiron

Nest.js의 Middleware, Interceptor, Pipe, Filter, Guard 본문

백엔드/Nest.js

Nest.js의 Middleware, Interceptor, Pipe, Filter, Guard

Lsiron 2024. 11. 1. 00:34

Nest.js에서는 Middleware, Interceptor, Pipe, Filter, Guard 가 있다.

이는 모두 비즈니스 로직 외적인 작업을 관리하며, 요청과 응답의 흐름을 조정하고, 애플리케이션의 안전성과 유연성을 높이는 역할을 한다는 점.

 

이들은 모두 애플리케이션의 요청-응답 사이클의 특정 지점에 개입하여 요청을 수정하거나, 유효성을 검사하거나, 권한을 확인하고, 에러를 처리하는 등의 작업을 수행할 수 있게 해 준다.

 

그럼 이제 하나씩 차례대로 파헤쳐보고 적절한 비유를 들어보자. 비유는 큰 틀로 집을 비유로 들 예정이다! 여기에서 집은 서버를 의미한다!

1. Middleware

Middleware는 클라이언트 요청이 서버의 라우트 핸들러에 도달하기 전에 공통적인 작업이나 사전 작업이 필요할 때 사용된다.

  • 예시: 사용자가 사이트에 로그인되어 있는지 확인하는 Middleware를 추가할 수 있다. 요청이 들어오면 먼저 Middleware에서 로그인 상태를 체크하고, 로그인되지 않은 경우 라우트에 접근하지 못하게 막을 수 있다.
    • 로그인 상태나 인증 확인: 사용자가 특정 URL에 접근하기 전에 로그인되어 있는지 확인하고, 로그인되지 않은 경우 접근을 차단할 때.
    • 로깅: 모든 요청 정보를 로그에 기록해야 할 때, 요청에 대한 기본적인 정보를 수집하기 위해 사용.
    • CORS 설정: 모든 요청에서 특정 도메인만 접근할 수 있도록 제어해야 할 때.

공통으로 처리해야 할 작업이 여러 경로에 걸쳐서 필요할 때, 또는 특정한 요청 패턴을 걸러내거나 데이터를 조정해야 할 때 사용한다. 

 

이는 즉, 집에 들어오기 전에 신발을 벗는 과정이다! 집(서버)에 들어가기 전에 신발을 벗는(로그인 여부를 확인) 것. 신발을 벗어야만 집으로 들어갈 수 있는 것처럼, Middleware에서 체크를 통과해야 요청이 다음 단계로 넘어갈 수 있다.

2. Interceptor

Interceptor는 요청과 응답을 가로채어 추가적인 처리를 할 때 사용된다. 요청 전, 혹은 응답 직후에 작업이 필요한 경우 적합하다.

  • 예시: 응답 데이터를 변환하는 Interceptor를 만들 수 있다. 예를 들어, 모든 응답에 추가 정보를 자동으로 추가해주는 Interceptor를 구현할 수 있다.
    • 응답 데이터 변환: 데이터베이스에서 받은 응답을 클라이언트가 보기 좋게 변환해서 보내야 할 때.
    • 응답 시간 측정: 요청이 처리되는 데 걸린 시간을 로깅해야 할 때.
    • 캐싱: 응답 데이터를 캐시에 저장해서 동일한 요청에 대해 빠르게 응답할 때.

주로 성능을 높이거나, 클라이언트가 데이터를 처리하기 쉽게 데이터를 변경해야 할 때, 혹은 서버 응답 후에도 추가적인 작업이 필요할 때 사용한다.

 

음 다르게 말하자면, 집(서버)에 들어오기 전에 집 열쇠나 필요한 물건을 가지고 있는지 다시 한 번 확인하고, 집에서 나갈 때도 불이 꺼졌는지, 창문이 잠겼는지 확인하며 필요한 물건을 챙겼는지 확인하는 과정을 떠올려 보자! 이 과정은 요청이 들어오기 전과 나가기 전에 중간에 확인하고 필요한 추가 작업을 수행하는 것과 같다. 보통 이렇게 확인하는 과정은 갑자기 떠오르는 것(가로챔)이다. 

3. Pipe

Pipe는 데이터 유효성 검사와 변환 작업이 필요할 때 사용된다. 주로 클라이언트에서 보낸 데이터를 가공하여 라우트 핸들러로 보내기 전에 데이터의 유효성을 검사하거나 데이터 형식을 변환한다.

  • 예시: 숫자로만 이루어진 ‘나이’를 받는 라우트가 있을 때, 입력이 숫자가 아닐 경우 에러를 반환하게 하는 Validation Pipe를 설정할 수 있다.
    • 데이터 유효성 검사: 입력된 값이 필수적인지, 특정 형식을 만족하는지 확인할 때.
    • 데이터 변환: 문자열로 받은 숫자를 숫자 타입으로 변환하거나, 요청 데이터를 다른 형식으로 변경할 때.

사용자가 보낸 데이터가 백엔드 시스템이 필요로 하는 형식과 맞지 않는 경우, 혹은 사전에 데이터를 필터링해 잘못된 데이터가 처리되지 않도록 막아야 할 때 적합하다.

 

이 과정을 집(서버)에 들어오려는 사람이 신분증을 보여주고, 가방을 검사받는 과정이라고 생각해 보자! 이때, 사람이 누구인지, 가져온 물건이 무엇인지 등을 확인하는 셈이다!

4. Filter

Filter는 애플리케이션에서 발생하는 에러를 처리하고, 적절하게 응답할 때 사용된다.

  • 예시: 사용자가 접근할 수 없는 자원에 접근하려고 할 때 에러 메시지를 만들어 클라이언트에게 전달하는 Filter를 만들 수 있다.
    • 에러 핸들링: 특정한 타입의 에러가 발생할 때 사용자에게 적절한 에러 메시지를 보내야 할 때.
    • 로그 작성: 에러 발생 시 로그에 해당 에러를 기록하거나 알림을 보낼 때.
    • 응답 포맷 관리: 에러 메시지의 형식을 일관되게 클라이언트에게 전달하고 싶을 때.

서버에서 발생한 다양한 에러를 클라이언트에게 체계적이고 이해하기 쉬운 방식으로 전달해야 할 때 사용된다.

 

집안에서 냉장고 문이 열려 있거나, 가스밸브가 잠기지 않았을 때 경고음을 울려서 알려주는 알림 장치와 같다! 이 알림 시스템은 어떤 문제가 발생했는지 즉각적으로 알려주며, 필요한 정보를 제공해 문제를 확인하고 처리할 수 있게 해 주는 것.

5. Guard

Guard는 요청이 특정 라우트에 접근할 자격이 있는지(주로 인증 및 권한 관련) 확인할 때 사용된다.

  • 예시: 관리자 권한이 필요한 API에 Guard를 걸어, 관리자가 아닌 경우 접근하지 못하게 막을 수 있다.
    • 권한 관리: 특정 역할(관리자)만 특정한 API에 접근할 수 있도록 제어할 때.
    • 인증 확인: 로그인 상태가 아닐 경우 특정 경로에 접근하지 못하도록 제한할 때.
    • 특정 조건 확인: 사용자의 요청이 특정 조건(사용자 상태가 활성 상태)일 때만 라우트에 접근할 수 있도록 할 때.

요청을 처리하기 전에 사용자가 해당 작업을 수행할 권한이나 자격이 있는지를 확인해야 할 때 사용한다. 관리자나 특정 권한을 가진 사용자만 접근할 수 있도록 하는 경우 등에 적합하다.

 

보안요원이 집에 들어오려는 사람에게 "초대받은 사람입니까?", "거주자가 맞나요?"와 같은 질문을 해서, 집에 들어올 권한이 있는지 확인하는 셈이다!