"프레임워크가 http 모듈 숨겨. http 모듈 읽으면 프레임워크 안 필요해져 — 또는 최소한 그게 너 대신 뭘 하는지 이해해."
10 줄 서버
import { createServer } from 'node:http';
const server = createServer((req, res) => {
// req is an http.IncomingMessage (a Readable stream)
// res is an http.ServerResponse (a Writable stream)
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end(`hi, you asked for ${req.url}\n`);
});
server.listen(3000, () => {
console.log('http://localhost:3000');
});
이게 완전한 프로덕션-모양 HTTP 서버. Express 없음, Koa 없음, Fastify 없음. 네가 쓴 모든 프레임워크가 정확히 이 API 위의 레이어야. Handler 가 모든 request 마다 돔; req 와 res 는 stream; listen() 가 포트 바인드.
Request 의 해부
req (IncomingMessage) 가 들고 있는 거:
req.method— 'GET', 'POST' 등.req.url— path + query string, 예:/api/users?id=5.req.headers— 소문자 header 이름의 값 객체.- Body 는 Readable stream —
for await (const chunk of req)로 소비.
Response 의 해부
res (ServerResponse) 로:
res.writeHead(statusCode, headersObject)— status 와 header 한 번에.res.setHeader(name, value)— 단일 header.res.write(chunk)— body 에 쓰기. 여러 번 호출 허용.res.end([chunk])— 마무리하고 닫기. 필수.
res.end() 까먹으면 클라이언트가 영원히 hang. 보통 쓰는 프레임워크가 이 계약 wrap 하고 end 호출 보장; http 모듈은 단속 안 함.
Request Body 읽기
import { createServer } from 'node:http';
import { json } from 'node:stream/consumers';
createServer(async (req, res) => {
if (req.method === 'POST' && req.url === '/api/users') {
try {
const body = await json(req); // consume + parse in one helper
console.log('got user:', body.name);
res.writeHead(201, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ id: 42, ...body }));
} catch (e) {
res.writeHead(400);
res.end('bad json');
}
}
}).listen(3000);node:stream/consumers 모듈 (Node 16+) 이 text(), json(), buffer(), arrayBuffer(), blob() 제공 — 각자 stream 을 명명된 모양으로 완전 소비. 모든 Node 튜토리얼이 가르치던 수동 청크-누적 춤 대체.나가는 HTTP — 옛 방식
http 모듈에 http.request / http.get 통한 클라이언트 쪽도 있어. 2026 엔 HTTP 클라이언트로 이거 안 씀 — fetch (다음 레슨) 가 보편 답. 예외는 underlying 소켓의 정밀 컨트롤 필요할 때: keep-alive 정책, 커스텀 DNS resolution, raw stream 접근. 99% 의 나가는 HTTP 엔 fetch 가 옳음.
HTTPS — 같은 API, 다른 모듈
node:https 가 구조적으로 node:http 와 동일하지만 TLS 추가. createServer(options, handler) 가 서버 인증서용 { key, cert } 받음. 대부분 프로덕션 배포가 reverse proxy (nginx, Cloudflare, 클라우드 로드 밸런서) 에서 TLS 종료, 내부적으로 plain http 서빙 — cert-rotation 골치 적고, 프로세스 재시작 쉬움. day one 에 TLS 가 stack 어디 살지 결정.