Node Functions 개발자 가이드

Ethan MercerEthan Mercer
30 분 읽기
Spt 3, 2025

Node Functions란 무엇인가요?

Node Functions는 개발자에게 원활한 동적 백엔드 기능을 제공하도록 설계된 EdgeOne의 포괄적인 서버리스 함수 솔루션입니다. 프로젝트의 /node-functions 디렉토리 내에 Node 함수를 생성하기만 하면 코드가 자동으로 강력한 Node.js 기반 API 엔드포인트로 변환됩니다. 

이러한 엔드포인트는 데이터베이스 쿼리, 서드파티 API 통합, 양식 제출 및 데이터 처리 작업을 포함한 광범위한 백엔드 작업을 효율적으로 처리할 수 있으며, 서버 관리의 복잡성을 제거합니다. 이 서버리스 접근 방식은 Node Functions를 확장 가능하고 현대적인 애플리케이션을 구축하기 위한 완벽한 기반으로 만듭니다.

Node Functions 통합의 주요 이점

통합된 프론트엔드와 백엔드 코드 관리로 진정한 풀스택 개발을 경험하세요. 프론트엔드 정적 자산과 백엔드 함수 로직을 단일 Git 저장소에 보관하여 구성, 환경 변수 및 배포 파이프라인을 원활하게 공유할 수 있습니다. "git push" 명령 하나로 전체 애플리케이션 스택을 배포하여 개발 워크플로우를 획기적으로 간소화하고 운영 오버헤드와 유지 관리 복잡성을 최소화할 수 있습니다.

손끝에서 방대한 npm 생태계의 모든 힘을 활용하세요. 데이터베이스 드라이버, 유틸리티 라이브러리, SDK를 포함한 수백만 개의 npm 패키지를 서버리스 함수에 원활하게 통합할 수 있습니다. 이 풍부한 생태계는 개발자가 기존 솔루션을 처음부터 다시 구축하는 대신 혁신적인 비즈니스 로직을 만드는 데 집중할 수 있게 합니다.

Node Functions의 10가지 필수 사용 사례 및 기능

Node Functions는 전통적인 CRUD 작업을 넘어 개발자가 정교한 예약 작업을 실행하고, 안전한 결제를 처리하며, 실시간 알림을 전달하고, 다양한 고급 기능을 구현할 수 있도록 지원합니다. 아래에서 가장 실용적인 10가지 사용 사례를 확인해보세요. 각 사례는 프로젝트 기능과 사용자 경험에 변화를 주고 측정 가능한 개선을 제공하도록 설계되었습니다. 

아래 샘플 코드의 전체 구조가 포함된 샘플 코드 저장소를 방문하세요.

API 요청 처리 및 관리

API 요청 처리는 현대 웹 애플리케이션의 기본 초석으로, 다양한 HTTP 요청(GET, POST, PUT, DELETE)을 원활하게 수신하고 응답합니다. 이 필수 기능은 프론트엔드 애플리케이션을 위한 강력한 데이터 인터페이스 서비스를 제공하여 프론트엔드-백엔드 데이터 통신을 위한 중요한 연결고리를 구축합니다. 

다음 예시에서 간소화된 GET 요청 구현을 살펴보세요. 

export async function onRequest(context) {
  const { request } = context;
  
  try {
    if (request.method === 'GET') {
      const users = [
        { id: 1, name: 'John', email: 'john@example.com' },
      ];
      return new Response(JSON.stringify(users), {
        headers: { 'Content-Type': 'application/json' }
      });
    }
    
    return new Response(JSON.stringify({ error: 'Resource not found' }), {
      status: 404,
      headers: { 'Content-Type': 'application/json' }
    });
  } catch (error) {
    // Handle errors
    return new Response(JSON.stringify({ error: 'Internal server error' }), {
      status: 500,
      headers: { 'Content-Type': 'application/json' }
    });
  }
}

OpenAI API 서비스 통합

Node.js 환경은 제로 구성 설정으로 표준 OpenAI SDK를 원활하게 통합하여 강력한 AI 기능에 즉시 액세스할 수 있습니다. 환경 변수를 활용하여 API 키를 안전하게 관리함으로써 이 접근 방식은 코드 유연성과 배포 민첩성을 유지하면서 기업 수준의 보안을 보장합니다. 

다음 예시에서 Deepseek 텍스트 생성 모델 통합을 살펴보세요.

import OpenAI from "openai";
import getRequestBody from '../getRequestBody.js';

export async function onRequest(context) {
  const { request } = context;
  
  try {
    // Parse request body
    const { prompt, maxTokens = 500 } = await getRequestBody(request);
    
    if (!prompt) {
      return new Response(JSON.stringify({ error: 'No prompt provided' }), { status: 400 });
    }
    
    // Initialize OpenAI client
    const openai = new OpenAI({
      baseURL: process.env.OPENAI_API_URL,
      apiKey: process.env.OPENAI_API_KEY
    });
    
    // Call API.chat.completions.create({
      model: "deepseek-ai/DeepSeek-R1-0528",
      messages: [
        { role: "system", content: "You are a helpful AI assistant." },
        { role: "user", content: prompt }
      ],
      max_tokens: maxTokens
    });
    
    // Return generated text
    return new Response(JSON.stringify({
      generatedText: completion.choices[0].message.content
    }), {
      headers: { 'Content-Type': 'application/json' }
    });
    
  } catch (error) {
    return new Response(JSON.stringify({ error: error.message }), { status: 500 });
  }
}

데이터베이스 통합 및 연결

다양한 데이터베이스 작업을 함수 내에서 원활하게 통합하여 주요 데이터베이스 연결 및 CRUD 작업을 지원합니다. 서버리스 아키텍처를 통해 데이터 지속성, 실시간 쿼리 및 복잡한 데이터 처리 로직을 쉽게 구현하고 동적 애플리케이션에 대한 포괄적인 백엔드 데이터 지원을 제공합니다.

데이터베이스 작업을 위해 직접 사용하거나 프로젝트 개발에 참조할 수 있는 완전한 풀스택 데이터베이스 배포 템플릿을 제공합니다.

신원 인증 및 세션 제어

JWT 토큰을 통해 함수에서 무상태 인증을 구현합니다. 사용자 등록, 로그인 확인, 토큰 생성 및 유효성 검사와 같은 핵심 기능을 지원하고, 클라우드 데이터베이스 서비스와 함께 작동하여 사용자 정보를 저장하며, Supabase와 같은 타사 인증 메커니즘과 통합하여 사용자 관리 개발을 가속화할 수 있습니다.

다음에서 간소화된 로그인 인증 구현을 살펴보세요.

const JWT_SECRET = process.env.JWT_SECRET;
const JWT_EXPIRES_IN = '24h';

function hashPassword(password) {
  return crypto.createHash('sha256').update(password).digest('hex');
}

function generateToken(payload) {
  return jwt.sign(payload, JWT_SECRET, { expiresIn: JWT_EXPIRES_IN });
}

export async function onRequest(context) {
  const { request } = context;
  
  try {
    return await handleLogin(request);
  } catch (error) {
    // errors handling
  }
}


async function handleLogin(request) {
  const data = await getRequestBody(request);
  const { email, password } = data;
  
  if (!email || !password) {
    ...
  }
  
  const user = users.find(u => u.email === email);
  if (!user) {
    ...
  }
  
  const hashedPassword = hashPassword(password);
  if (user.password !== hashedPassword) {
    ...
  }
  
  const token = generateToken({ userId: user.id });
  
  const { password: _, ...userWithoutPassword } = user;
  return new Response(JSON.stringify({
    message: 'Login successful',
    user: userWithoutPassword,
    token
  }), {
    headers: { 'Content-Type': 'application/json' }
  });
}

이메일/푸시 알림 전송

Resend, Nodemailer, SendGrid, AWS SES와 같은 이메일 서비스 제공업체 API를 통해 함수 내에서 이메일 전송을 구현하여 HTML 리치 텍스트, 첨부 파일 및 템플릿 렌더링과 같은 기능을 지원합니다. 또한 SMS 및 푸시 알림을 포함한 다중 채널 메시징 서비스를 통합하여 사용자 등록 확인, 주문 알림 및 시스템 경고와 같은 시나리오에 적합합니다.

다음 Resend 구현 예시를 살펴보세요.

export async function onRequest(context) {
  const { request } = context;
  const resend = new Resend(process.env.RESEND_API_KEY);


  try {
    const requestBody = await getRequestBody(request);
    
    // Validate request parameters
    if (!requestBody || !requestBody.email) {
      return new Response(JSON.stringify({ error: 'Missing email address' }), {
        status: 400,
        headers: { 'Content-Type': 'application/json' }
      });
    }
    
    const { email } = requestBody;
    const name = requestBody.name || 'User';
    const subject = requestBody.subject || 'Welcome to our service';
    const customMessage = requestBody.message || '';
    
    // Send email
    const data = await resend.emails.send({
      from: 'noreply@wenyiqing.email', // Replace with your sender email
      to: [email],
      subject: subject,
      html: `
        <div style="font-family: sans-serif; max-width: 600px; margin: 0 auto;">
          <h2>Hello, ${name}!</h2>
          <p>Thank you for using our service.</p>
          ${customMessage ? `<p>${customMessage}</p>` : ''}
          <p>If you have any questions, please feel free to contact us.</p>
          <p>Best regards,<br>The Team</p>
        </div>
      `
    });
    if(data.error) {
      // errors handling
    }
    // Return success response
    return new Response(JSON.stringify({ success: true, messageId: data.id }), {
      status: 200,
      headers: { 'Content-Type': 'application/json' }
    });
  } catch (error) {
    // errors handling
  }
}

데이터 형식 변환

서버리스 함수 내에서 강력한 범용 형식 변환 기능을 활용하세요. xml2js, csv-parser, xlsx, pdfkit과 같은 업계에서 검증된 라이브러리를 포함한 Node.js의 광범위한 파싱 생태계의 모든 잠재력을 활용하여 파일 처리, API 통합 및 기업 보고 시나리오에 걸친 복잡한 데이터 워크플로우를 손쉽게 조율하세요. 

표준화된 형식 변환 API를 제공하는 전용 데이터 변환 마이크로서비스로 배포하여 프론트엔드 애플리케이션과 외부 시스템에 권한을 부여하는 동시에 크로스 플랫폼 데이터 교환 복잡성을 극적으로 줄입니다.

이 간소화된 CSV-to-XLSX 변환 예제를 살펴보세요.

import getRequestBody from '../getRequestBody.js';
import * as XLSX from 'xlsx';

function convertCsvToExcel(csvData, options = {}) {
  	// 데이터 변환 로직
}

export async function onRequest(context) {
  const { request } = context;
  
  try {
    // 요청 본문에서 CSV 데이터 가져오기
    const requestBody = await getRequestBody(request);
    const csvData = requestBody;
    
    // URL 매개변수에서 옵션 가져오기
    ...
    const options = {...};
    
    // CSV를 Excel로 변환
    const excelBuffer = convertCsvToExcel(csvData, options);
    
    // Excel 파일을 다운로드 가능한 형태로 반환
    const filename = params.get('filename') || 'data.xlsx';
    return new Response(excelBuffer, {
      status: 200,
      headers: {
        'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
        'Content-Disposition': `attachment; filename="${filename}"`
      }
    });
  } catch (error) {
    // 간단한 오류 응답
    return new Response(JSON.stringify({ error: error.message }), { status: 400 });
  }
}

// 참고: 간결성을 위해 CSV 검증 로직 생략
// 프로덕션에서는 변환 전에 CSV 형식을 검증해야 합니다

웹훅 이벤트 처리

서버리스 함수 내에서 이벤트 중심 아키텍처 패러다임과 원활하게 정렬되도록 설계된 엔터프라이즈급 고가용성 웹훅 엔드포인트를 구축하세요. GitHub, Stripe 등을 포함한 주요 플랫폼에서 실시간 이벤트 스트리밍을 활성화하고, 인증된 요청 출처와 완벽한 보안 프로토콜을 보장하기 위한 암호화 서명 검증을 구현하세요. 

우리의 웹훅 처리 기능을 보여주는 이 GitHub 푸시 이벤트 통합 예제를 확인하세요.

export async function onRequest(context) {
  const { request, env } = context;
  try {
    const webhookSecret = env.GITHUB_WEBHOOK_SECRET;
    
    const clonedRequest = cloneRequest(request);
    const isSignatureValid = await verifyGitHubSignature(clonedRequest, webhookSecret);
    
    if (!isSignatureValid) {
      // errors handling
    }
    // Get event type
    const eventType = request.headers['x-github-event'];
    if (!eventType) {
      // errors handling
    }
    // Parse request body
    const payload = await await getRequestBody(request);
    // Process based on event type
    let result;
    switch (eventType) {
      case 'ping':
        result = { status: 'success', message: 'Pong! Webhook configured successfully' };
        break;
      case 'push':
        result = handlePushEvent(payload);
        break;
      case 'pull_request':
        result = handlePullRequestEvent(payload);
        break;
      case 'issues':
        result = handleIssueEvent(payload);
        break;
      default:
        result = { 
          status: 'received', 
          message: `Received ${eventType} event, but no handler implemented` 
        };
    }
    
    // Return processing result
    return new Response(JSON.stringify(result), {
      status: 200,
      headers: {
        'Content-Type': 'application/json'
      }
    });
  } catch (error) {
    // errors handling
  }
}

파일 업로드 및 처리 서비스

서버리스 함수 내에서 이미지, 비디오 및 문서를 포함한 다양한 미디어 유형에 대한 포괄적인 multipart/form-data 처리 기능을 갖춘 고성능 파일 업로드 인프라를 구축하세요. Multer 및 Busboy와 같은 업계 표준 미들웨어 솔루션을 활용하여 정교한 업로드 스트림 파싱을 조율하세요. Tencent Cloud COS, AWS S3, Alibaba Cloud OSS를 포함한 주요 클라우드 스토리지 플랫폼과 원활하게 통합하여 탄력적인 영구 스토리지 솔루션을 제공하세요.

우리의 Node Functions 아키텍처를 통한 Tencent Cloud COS 직접 통합으로 원활한 사용자 파일 업로드를 보여주는 이 엔드 투 엔드 구현을 살펴보세요.

// COS Configuration (simplified)
const cos = new COS({...});

const MAX_FILE_SIZE = 100 * 1024 * 1024;

function generateSafeFilename(originalFilename, mimeType) {
	...
}

async function uploadToCOS(fileData, filename, mimeType) {
  // Tencent Cloud COS upload logic...
}

export async function onRequest(context) {
  const req = context.request;

  try {
    return new Promise((resolve, reject) => {
      const bb = busboy({ headers: req.headers });
      const uploadResults = [];
      
      // Process file fields
      bb.on('file', (fieldname, file, { filename, mimeType }) => {
        const chunks = [];
        let fileSize = 0;
        
        file.on('data', (data) => {
          chunks.push(data);
          fileSize += data.length;
          
          if (fileSize > MAX_FILE_SIZE) {
            file.resume(); // Stop receiving
          }
        });

        file.on('end', async () => {
          if (fileSize > MAX_FILE_SIZE) {
            return; // Skip oversized files
          }
          
          try {
            // Process and upload file
            const fileData = Buffer.concat(chunks);
            const safeFilename = generateSafeFilename(filename, mimeType);
            const result = await uploadToCOS(fileData, safeFilename, mimeType);
            
            uploadResults.push({
              fieldname,
              ...result
            });
          } catch (err) {
            console.error('Upload error:', err);
          }
        });
      });

      bb.on('finish', () => {
        resolve(new Response(JSON.stringify({
          success: true,
          files: uploadResults
        }), { status: 200 }));
      });

      req.pipe(bb);
    });
  } catch (error) {
    return new Response(JSON.stringify({ error: 'Upload failed' }), { status: 500 });
  }
}

이미지 및 비디오 처리 엔진

서버리스 함수 내에서 업계 최고의 이미지 처리 라이브러리인 Sharp와 Jimp의 모든 잠재력을 활용하여 정밀한 스케일링, 지능형 크로핑, 동적 워터마킹, 원활한 형식 변환 및 적응형 품질 압축을 포함한 정교한 시각적 변환을 조율하세요. FFmpeg 및 Fluent-ffmpeg 통합을 통해 전문급 비디오 편집 워크플로우, 고성능 트랜스코딩 파이프라인, 지능형 프레임 추출 및 자동화된 썸네일 생성 시스템을 가능하게 하는 고급 비디오 처리 기능을 배포하세요.

최적화된 Node Functions 아키텍처를 통한 base64 이미지 수집을 보여주는 이 정교한 예제를 살펴보세요.

export async function onRequest(context) {
  const { request } = context;

  try {
    const requestBody = await getRequestBody(request);
    
    let base64Data = requestBody.image;
    if (base64Data.includes(';base64,')) {
      base64Data = base64Data.split(';base64,')[1];
    }
    
    const imageBuffer = Buffer.from(base64Data, 'base64');
    
    // 워터마크 매개변수 가져오기
    const watermarkText = requestBody.text || '워터마크 예제';
    const opacity = parseFloat(requestBody.opacity || '0.5');
    const textColor = requestBody.textColor || 'white';
    const fontSize = parseInt(requestBody.fontSize || '36', 10);
    
    const imageInfo = await sharp(imageBuffer).metadata();
    const imageMimeType = `image/${imageInfo.format}`;
    
    const processedImageBuffer = await addTextWatermark(
      imageBuffer,
      watermarkText,
      opacity,
      textColor,
      fontSize
    );
    
    // 처리된 이미지 반환
    return new Response(processedImageBuffer, {
      status: 200,
      headers: { 'Content-Type': imageMimeType }
    });
  } catch (error) {
    // 오류 처리
  }
}

서버 전송 이벤트

함수 내에서 실시간 통신 기능을 구축하여 서버 전송 이벤트(SSE)를 통한 단방향 데이터 스트림 푸싱을 구현하거나 WebSocket 게이트웨이 서비스와 통합하여 양방향 실시간 통신을 달성하세요.

메시지 큐(Redis Pub/Sub, Kafka, RabbitMQ 등)를 중개자로 활용하여 함수는 주식 시세, 스포츠 점수, 주문 상태 및 시스템 모니터링을 포함한 실시간 데이터를 구독하고 푸시할 수 있습니다. 호환성 요구 사항을 위한 롱 폴링 메커니즘을 지원하고, 스트림 처리를 위한 함수 체인 호출을 통해 데이터 필터링, 집계 및 변환을 구현하세요.

아래는 SSE 서버 측 기능 구현을 보여주는 코드 예제입니다.

const clients = new Set();

// 메시지 큐 시뮬레이션
const messageQueue = {
  subscribers: {},
  publish: function(channel, message) {
    ...
  },
  subscribe: function(channel, callback) {
    ...
  }
};

// 주식 데이터 생성기 시뮬레이션
function generateStockData() {
  ...
}

// 시뮬레이션 데이터 게시 시작
let stockDataInterval {
	// 2초마다 데이터 전송
	...
}

// 시뮬레이션 데이터 게시 중지
function stopStockDataSimulation() {
  if (stockDataInterval && clients.size === 0) {
    clearInterval(stockDataInterval);
    stockDataInterval = null;
  }
}

export async function onRequest(context) {
  const { request, env } = context;
  
  const url = new URL(request.url, 'http://www.example.com');
  const channel = url.searchParams.get('channel') || 'stocks';
  
  const responseStream = new TransformStream();
  const writer = responseStream.writable.getWriter();
  
  // SSE 응답 헤더 설정
  constreadable, {
    headers: {
      'Content-Type': 'text/event-stream',
      'Cache-Control': 'no-cache',
      'Connection': 'keep-alive',
    }
  });
  
  // 클라이언트 객체 생성
  const clientId = Date.now().toString();
  const client = {
    id: clientId,
    writer
  };
  
  // 연결 컬렉션에 클라이언트 추가
  clients.add(client);
  
  if (clients.size === 1) {
    startStockDataSimulation();
  }
  
  // 연결 성공 메시지 전송: connected\ndata: {"clientId":"${clientId}","message":"연결 성공"}\n\n`;
  await writer.write(new TextEncoder().encode(connectMessage));
  
  // 메시지 큐 구독
  const unsubscribe = messageQueue.subscribe(channel, async (data) => {
    const eventData = `event: message\ndata: ${JSON.stringify(data)}\n\n`;
    await writer.write(new TextEncoder().encode(eventData));
  });
  
  // 연결 종료 수신
  context.waitUntil(
    (async () => {
      try {
        await request.signal.aborted;
      } catch (error) {
        // 오류 처리
      } finally {
        // 리소스 정리
      }
    })()
  );
  
  return response;
}

원활한 연결 테스트를 위해 이 클라이언트 측 구현을 사용하여 실시간 통신 인프라를 검증하세요.

결론

Node Functions 은 현대 웹 개발 패러다임의 진화적 도약을 상징합니다. 혁신적인 서버리스 컴퓨팅 프레임워크를 통해 개발 조직은 기존의 인프라 제약을 뛰어넘어 서버 프로비저닝 오버헤드, 자동화된 스케일링 복잡성 및 로드 밸런싱 오케스트레이션을 제거하여 전략적 비즈니스 로직 구현과 혁신 가속화에 레이저 같은 집중을 가능하게 합니다.

Node Functions 의 기능은 간소화된 API 마이크로서비스부터 AI 통합, 기본 데이터 지속성 아키텍처부터 실시간 이벤트 스트리밍 인프라, 지능형 파일 처리 워크플로우부터 고급 멀티미디어 변환 파이프라인까지 포괄적인 스펙트럼을 포함하여 애플리케이션 개발의 모든 차원에 걸쳐 포괄적인 커버리지를 제공합니다.

단일 Git 저장소, 통합 배포 파이프라인 및 중앙 집중식 환경 구성이 개발부터 글로벌 프로덕션 배포까지 완전한 애플리케이션 라이프사이클을 조율합니다. 

개인 혁신 프로젝트를 설계하든, 파괴적인 스타트업 제품을 확장하든, 미션 크리티컬한 엔터프라이즈 솔루션을 엔지니어링하든, Node Functions 은 신속한 프로토타이핑부터 프로덕션 규모 배포까지 포괄적인 엔드 투 엔드 개발 플랫폼을 제공하여 업계의 궁극적인 개발 비전인 "한 번 설계하고, 어디서나 배포하고, 무한히 확장하라"를 진정으로 실현합니다.