logo
Published on

[짧은 글] Multipart/Form-Data를 왜 Stream으로 처리해야 할까

Authors
  • avatar
    Name
    MJ
    Twitter

[짧은 글] Multipart/Form-Data에 대해서

업무 중 Nest.js에서 파일 업로드 기능을 구현하게 되었어요.
브라우저는 파일 업로드 시 데이터를 multipart/form-data 형식으로 전송하죠.
Nest.js에서는 이를 처리할 때, 요청을 parts로 나누고 **이터레이터(iterator)**를 통해 하나씩 꺼내 처리하는 방식으로 구현되어 있었어요.
왜 이렇게 구현되어 있는지 궁금해서 조사해봤어요.

Node.js의 Request 객체는 Stream이에요.

Node.js의 요청 객체(req)는 기본적으로 Readable Stream입니다.
multipart/form-data는 업로드되는 데이터(특히 파일)의 크기가 크기 때문에,
요청 본문을 한 번에 모두 메모리에 올리는 방식은 메모리 부족을 초래할 수 있어요.

따라서 Node.js에서는 스트리밍(Streaming) 방식으로 데이터를 조금씩(chunk 단위로) 읽어 들이는 방식을 사용합니다.
이는 메모리 효율성이 높고, 대용량 파일도 안정적으로 처리할 수 있어요.

이름부터 multipart/form-data입니다.

이 요청 형식은 말 그대로 **여러 개의 파트(part)**로 구성돼 있어요.
예를 들어 텍스트 필드, 파일, 체크박스 등의 값들이 각각의 파트로 나뉘어 전송됩니다.
그리고 각 파트는 저마다 **헤더와 본문(body)**을 가지기 때문에, 이를 적절히 분리하고 처리해야 합니다.

Nest.js에서 req.parts() 같은 API를 통해 각 파트를 순회하면서,
텍스트는 메모리로, 파일은 스트림으로 처리할 수 있게 되어 있어요.
이 덕분에 다양한 타입의 폼 필드를 유연하게 처리할 수 있습니다.

마무리하며

결국 multipart/form-data는 구조적으로도, 처리 방식으로도 스트리밍이 자연스럽고 효율적인 방식이에요.
Nest.js도 이런 점을 반영해 part 기반의 이터레이터 처리를 제공하고 있고요.

참고로 스트리밍 데이터는 전송 중에도 TCP 연결이 유지되므로 걱정할 필요는 없지만, 적절한 timeout 설정은 꼭 고려해줘야 합니다.