# Vercel 서버리스 함수란?

Vercel 서버리스 함수는 서버를 직접 관리하지 않고, 백엔드 로직을 실행할 수 있는 기능이에요. 기본적으로 상태가 없는 `Stateless` 하며, 각 요청은 독립적으로 처리되어요. 함수는 HTTP 요청이 들어올 때만 실행이 되고, 유후 상태에서는 비용이 발생되지 않아요. 또, 트래픽에 따라 자동으로 인스턴스가 늘어나는 구조를 가지게 됩니다.

## /api 폴더 아키텍쳐로 서버리스 함수 구현해보기

비교적 간단하게 사용을 할 수 있는데, 아래와 같은 예제로 구성을 할 수 있어요.

서버리스 함수는 서버가 없어도 호출할 수 있는 구조이기에, 단순한 정적 사이트에서도 API 호출을 테스트하거나 간단한 서버 로직을 구현하는데 활용 할 수 있어요. 프론트엔드 중심의 프로젝트에서 별도의 백엔드 환경 없이도 빠르게 데이터를 처리할 수 있다는 것이 강점인 것이죠.

```javascript
/api
  └── hello.ts       → GET /api/hello
  └── users/
        └── [id].ts  → GET /api/users/123 (동적 라우트)
```

```javascript
// api/hello.ts
// 만약 동적으로 하고 싶다면 api/post/[id].ts 형식으로 지정하면 된다.
import type { VercelRequest, VercelResponse } from '@vercel/node';
 
export default function handler(req: VercelRequest, res: VercelResponse) {
  res.status(200).json({ message: 'Hello!' });
}
```

```javascript
// app.ts
const response = await fetch('/api/hello');
const data = await response.json();
console.log(data.message);
```

## vercel.json으로 서버리스 함수 구현해보기

/api 폴더 아키텍쳐가 아닌 [vercel.json](https://vercel.json) 으로 서버리스 함수를 명시적으로 구현을 하는 방법도 존재해요. 만약 서버 자원이 아닌, 서버에서 `html` 을 받아 `html` 의 일부를 파싱하고, 수정하는 서버리스 함수를 만든다고 가정을 해볼게요.

```javascript
// server/server.cjs
// 아키텍쳐 구조는 분명 express.js의 자율적인 구조
 
const app = express();
 
// 프로젝트 루트 경로에서 dist 폴더 제공
const distPath = path.resolve(__dirname, "../dist"); // 절대 경로 사용
 
app.use(express.static(distPath));
 
app.get("/space/join/:id", async (req, res) => {
  const encryptedId = req.params.id;
  const filePath = path.join(distPath, "index.html"); // dist 경로에 있는 index.html 사용
  let html;
...
(이하 코드 생략)
```

```javascript
// vercel.json
{
  "version": 2, // 1은 deprecated라서 2버젼이 고정이라고 생각하면 된다.
  "builds": [
    {
      "src": "server/server.cjs",
      "use": "@vercel/node"
    } // Express 서버를 서버리스 함수로 변환한다,
  ],
  "routes": [
    {
      "src": "/space/join/(.*)",
      "dest": "/server/server.cjs"
    }, // 이 경로로 오는 요청만 서버리스 함수로 보낸다.
  ]
}
```

## Vercel 서버리스 함수, 편하고 마냥 좋은거 아닌가요?

마냥 좋지만은 않아요. 콜드스타트 방식이면서 Vercel 서버리스 함수는 실행에 제약을 가지고 있는데, 기본은 10초 · Pro 플랜은 60초의 최대 요청 시간을 제공해요. 메모리는 최대 1GB이기 때문에 주의해서 사용을 해야합니다.

## Vercel 서버리스 함수의 동작 원리

일반 서버와 서버리스 함수를 비교해보면 아래와 같은 동작 원리를 가지게 되는 것을 볼 수 있어요.

```javascript
[일반 서버]
서버 시작 → 계속 대기 중 → 요청 처리 → 계속 대기 중...
(24시간 프로세스가 살아있음)
 
[서버리스]
요청 들어옴 → 함수 생성 → 요청 처리 → 함수 종료
(요청이 없으면 아무것도 없음)
```

요청이 들어올 때만 함수를 생성해서 요청을 처리한다는 것은 **"콜드 스타트"** 라는 방식이에요.

> **콜드 스타트와 웜 스타트?**

```javascript
[콜드 스타트] 첫 요청 or 오래 쉰 후
컨테이너 생성 + 코드 로드 + 실행 → 느림 (수백ms ~ 수초)
 
[웜 스타트] 연속 요청
이미 떠있는 컨테이너 재사용 → 빠름
```

위에서 확인한 콜드스타트의 개념을 차용해서 보면 Vercel 서버리스 함수는 아래와 같은 내부적인 세부 동작을 가지게 돼요.

```javascript
1. 사용자가 /space/join/abc 요청
          ↓
2. Vercel 엣지 네트워크가 요청 수신
          ↓
3. routes 규칙 확인 → server.cjs 매핑됨
          ↓
4. AWS Lambda 위에서 컨테이너 생성 (콜드 스타트)
          ↓
5. server.cjs 코드 로드 & 실행
          ↓
6. 응답 반환
          ↓
7. 컨테이너 대기 (일정 시간 후 소멸)
```

또 각각의 Vercel 서버리스 함수는 각 요청 시 마다 개별적이고 독립적으로 움직이게 됩니다.

```javascript
요청 A ─→ [컨테이너 1] 처리 후 종료
요청 B ─→ [컨테이너 2] 처리 후 종료
요청 C ─→ [컨테이너 1] 재사용 (웜 스타트)
```

For the site tree, see the [root Markdown](https://slashpage.com/timmy.md).
