본문 바로가기
개발

HTTP 통신의 실제 모습 – 라이브러리가 감추고 있던 바이트 스트림 처리

by 새싹 아빠 2025. 12. 9.

우리가 사용하는 RestTemplate, fetch, axios 같은 HTTP 클라이언트는 단순 호출만으로 요청을 보낼 수 있게 해 주기 때문에 내부에서 어떤 일이 일어나는지 알기 어렵습니다. 하지만 저수준 API인 HttpURLConnection을 직접 보면 HTTP 요청이 어떤 방식으로 구성되고 전송되는지 조금 더 명확하게 이해할 수 있습니다.

 

1. 저수준 HTTP 요청 코드 예시

아래는 JSON 데이터를 POST로 보내고, 응답을 문자열로 읽어오는 간단한 예시 코드입니다.

public static String sendJsonPost(String targetUrl, String jsonBody) throws IOException {
    URL url = new URL(targetUrl);
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();

    conn.setRequestMethod("POST");
    conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
    conn.setRequestProperty("Accept", "application/json");
    conn.setDoOutput(true);

    try (OutputStream out = conn.getOutputStream()) {
        byte[] data = jsonBody.getBytes(StandardCharsets.UTF_8);
        out.write(data);
    }

    StringBuilder responseText = new StringBuilder();
    try (BufferedReader reader =
                 new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8))) {

        String line;
        while ((line = reader.readLine()) != null) {
            responseText.append(line);
        }
    }

    return responseText.toString();
}

RestTemplate처럼 한 줄로 끝나는 코드는 내부적으로 이런 흐름을 수행합니다. 직접 구현된 버전을 보면 HTTP가 근본적으로 어떤 방식으로 동작하는지 더 잘 이해할 수 있습니다.

 

2. 문자열(JSON)을 바이트로 변환하는 이유

HTTP는 텍스트 기반 프로토콜처럼 보이지만, 실제로는 모든 요청과 응답이 바이트 스트림으로 전송됩니다. 따라서 문자열을 그대로 전송할 수 없고, 반드시 바이트 배열로 변환해야 합니다.

byte[] data = jsonBody.getBytes(StandardCharsets.UTF_8);
out.write(data);

이 과정은 다음과 같은 의미를 가집니다.

  • 문자열(JSON)을 UTF-8 인코딩으로 바이트 배열로 변환한다.
  • 변환된 바이트를 HTTP 요청 바디에 기록한다.

우리가 보던 fetchRestTemplate는 이 단계를 내부적으로 자동 처리하기 때문에 직접 이 과정을 볼 일이 거의 없습니다.

 

3. 응답을 읽는 과정도 결국 바이트 스트림 처리

BufferedReader reader =
    new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));

서버가 보내는 응답도 네트워크를 통해 바이트 흐름으로 도착합니다. 이를 지정된 문자셋(UTF-8)으로 다시 문자열로 복원하는 과정이 필요합니다.

 

4. 왜 평소에는 이런 코드를 보기 어려울까?

대부분의 개발 환경은 이미 고수준 HTTP 클라이언트를 제공하기 때문입니다.

  • 브라우저: fetch, axios
  • Spring: RestTemplate, WebClient
  • Android/Java: OkHttp

이 도구들은 스트림 생성, 바이트 변환, 예외 처리 등 모든 과정을 내부에서 처리하여 개발자가 신경 쓸 필요가 없도록 만들어 줍니다. 그렇기 때문에 실제 HTTP 요청이 어떤 구조인지 직접 볼 일이 많지 않습니다.

 

정리

  • HTTP 통신은 본질적으로 바이트 스트림 교환이다.
  • 고수준 라이브러리는 이 사실을 감춘 채 편한 인터페이스만 제공한다.
  • 저수준 API를 보면 요청·응답의 실제 동작 원리를 분명하게 이해할 수 있다.

가끔은 이런 내부 동작을 직접 확인해보는 것이 전체 구조를 이해하고, 예상치 못한 네트워크 문제를 해결하는 데에도 도움이 됩니다.