node:http
클라이언트 및 서버 API에 대한 지원을 추가하여 Cloudflare Workers에서 Node.js 응용 프로그램을 더 쉽게 실행할 수 있도록 합니다. 이번 추가로 친숙한 Node.js HTTP 인터페이스가 에지에 추가되어 기존 Express.js, Koa 및 기타 Node.js 애플리케이션을 전 세계에 제공합니다. 제로 콜드 스타트, 자동 확장, 대폭 단축된 사용자 대기 시간 등의 이점을 코드베이스를 다시 작성할 필요가 없습니다. 레거시 애플리케이션을 최신 서버리스 플랫폼으로 마이그레이션하든, 이미 알고 있는 API를 사용하여 새 애플리케이션을 구축하든, 이제 기존 개발 패턴과 프레임워크를 유지하면서 Workers의 전역 네트워크를 활용할 수 있습니다.
문제: Node.js 스타일 서버리스 환경의 HTTP
Cloudflare Workers는 직접 TCP 연결을 사용할 수 없는 고유한 서버리스 환경에서 작동합니다. 대신 모든 네트워킹 작업은 Workers 런타임 자체 외부의 특수 서비스에서 완전히 관리합니다. 이는 Open Egress 라우터(OER), Pingora 와 같이 연결 풀링, 연결 준비 상태 유지, 연결 IP 관리, 그리고 모든 복잡한 네트워킹 세부 정보를 처리하는 시스템입니다. 즉, 개발자는 TLS 협상, 연결 관리, 네트워크 최적화에 대해 걱정할 필요가 없습니다. 모두 자동으로 처리됩니다.
이러한 완전 관리형 접근 방식 때문에 실제로 특정 Node.js API를 지원할 수 없습니다. 이러한 네트워킹 결정은 성능 및 보안을 위해 시스템 수준에서 처리됩니다. 이러한 점에서 Workers는 기존 Node.js 환경과 차별화되지만, 복잡성이 없는 엔터프라이즈급 네트워킹을 확보하는 등 서버리스 컴퓨팅에 더 적합하다는 장점도 있습니다.
이 근본적인 차이로 인해 기존 Node.js 코드 패턴과의 호환성을 유지하면서 에지에서 HTTP API가 작동하는 방식을 재고해야 했습니다.
당사의 솔루션: Workers가 이미 뛰어난 성능을 발휘하고 있는 웹 표준 기술을 기반으로 구축하여 핵심 `node:http` API를 구현했습니다. 작동 방식은 다음과 같습니다.
node:http
클라이언트 구현에 사용자에게 친숙한 필수 API가 포함되어 있습니다.
당사의 이러한 API 구현은 Workers가 기본적으로 사용하는 표준 fetch()
API를 기반으로 구축되어 Node.js 호환성을 유지하면서 탁월한 성능을 제공합니다.
import http from 'node:http';
export default {
async fetch(request) {
// Use familiar Node.js HTTP client APIs
const { promise, resolve, reject } = Promise.withResolvers();
const req = http.get('https://api.example.com/data', (res) => {
let data = '';
res.on('data', chunk => data += chunk);
res.on('end', () => {
resolve(new Response(data, {
headers: { 'Content-Type': 'application/json' }
}));
});
});
req.on('error', reject);
return promise;
}
};
서버 측 구현에서 특히 흥미가 생깁니다. Workers는 특정 포트에서 수신 대기하는 기존 TCP 서버를 만들 수 없으므로, Node.js 스타일 서버를 Workers 요청 처리 모델에 연결하는 연결 시스템을 구축했습니다.
HTTP 서버를 만들고 TCP 소켓을 여는 대신 수신 대기(포트)를 호출하면 서버가 Worker 내의 내부 테이블에 등록됩니다.
이 내부 테이블은 http.createServer 실행 및 포트 번호를 식별자로 사용하여 들어오는 가져오기 요청을 처리합니다.
그런 다음 두 가지 방법 중 하나를 사용하여 들어오는 Worker 요청을 Node.js 스타일 서버와 연결합니다.
handleAsNodeRequest
를 이용한 수동 통합
이 접근 방식을 사용하면 Node.js HTTP 서버를 다른 Worker 기능과 통합할 수 있는 유연성이 제공되며, 기본 진입점 에 fetch
, reserved
, queue
등과 같은 여러 핸들러를 사용할 수 있습니다.
import { handleAsNodeRequest } from 'cloudflare:node';
import { createServer } from 'node:http';
// Create a traditional Node.js HTTP server
const server = createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello from Node.js HTTP server!');
});
// Register the server (doesn't actually bind to port 8080)
server.listen(8080);
// Bridge from Workers fetch handler to Node.js server
export default {
async fetch(request) {
// You can add custom logic here before forwarding
if (request.url.includes('/admin')) {
return new Response('Admin access', { status: 403 });
}
// Forward to the Node.js server
return handleAsNodeRequest(8080, request);
},
async queue(batch, env, ctx) {
for (const msg of batch.messages) {
msg.retry();
}
},
async scheduled(controller, env, ctx) {
ctx.waitUntil(doSomeTaskOnSchedule(controller));
},
};
이 접근 방식은 다음과 같은 경우에 적합합니다.
KV, Durable Objects, R2등 다른 Workers 기능과 통합
일부 경로는 다르게 처리하고 다른 경로는 Node.js 서버에 위임
사용자 지정 미들웨어 또는 요청 처리 적용
추가적인 기능이나 복잡성 없이 Node.js HTTP 서버를 통합하려는 사용 사례의 경우, `httpServerHandler` 함수를 사용할 수 있습니다. 이 함수는 자동으로 적분을 처리합니다. 이 솔루션은 Workers 전용 기능이 필요하지 않은 애플리케이션에 적합합니다.
import { httpServerHandler } from 'cloudflare:node';
import { createServer } from 'node:http';
// Create your Node.js HTTP server
const server = createServer((req, res) => {
if (req.url === '/') {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end('<h1>Welcome to my Node.js app on Workers!</h1>');
} else if (req.url === '/api/status') {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ status: 'ok', timestamp: Date.now() }));
} else {
res.writeHead(404, { 'Content-Type': 'text/plain' });
res.end('Not Found');
}
});
server.listen(8080);
// Export the server as a Workers handler
export default httpServerHandler({ port: 8080 });
// Or you can simply pass the http.Server instance directly:
// export default httpServerHandler(server);
이러한 HTTP API는 Express.js와 같은 인기 있는 Node.js 프레임워크를 Workers에서 실행할 수 있는 기회를 제공합니다. 이러한 프레임워크의 미들웨어가 예상대로 작동하지 않는 경우, Cloudflare Workers 리포지토리 에 이슈를 신고하세요.
import { httpServerHandler } from 'cloudflare:node';
import express from 'express';
const app = express();
app.get('/', (req, res) => {
res.json({ message: 'Express.js running on Cloudflare Workers!' });
});
app.get('/api/users/:id', (req, res) => {
res.json({
id: req.params.id,
name: 'User ' + req.params.id
});
});
app.listen(3000);
export default httpServerHandler({ port: 3000 });
// Or you can simply pass the http.Server instance directly:
// export default httpServerHandler(app.listen(3000));
Express.js 외에도 Koa.js 도 지원됩니다.
import Koa from 'koa';
import { httpServerHandler } from 'cloudflare:node';
const app = new Koa()
app.use(async ctx => {
ctx.body = 'Hello World';
});
app.listen(8080);
export default httpServerHandler({ port: 8080 });
node:http
및 node:https
API는 호환성 날짜가 2025년 8월 15일 이후인 nodejs_compat
호환성 플래그를 사용하여 Node.js 호환성을 활성화한 Workers에서 사용할 수 있습니다.
추가적인 node:http
지원을 통해 Cloudflare Workers를 새로운 응용 프로그램을 구축하든 기존 응용 프로그램을 마이그레이션하든 에지에서 JavaScript를 실행하기 위한 최고의 플랫폼으로 만들겠다는 목표에 더욱 가까워질 수 있습니다.
사용할 준비가 되셨나요? Worker에서 Node.js 호환성을 활성화 하고 에지에서 익숙한 HTTP API의 가능성을 탐색하기 시작합니다.