개발로 사고하기

🏢 아파트 실거래가 API 연동기 - 프록시 문제 해결

tues 2025. 10. 2. 14:24

https://apt-trade-web.vercel.app/

 

Vite + React + TS

 

apt-trade-web.vercel.app

 

1️⃣ 프록시를 쓴 이유

서울시 공공데이터포털에서 제공하는 아파트 매매 실거래가 API를 React 프론트엔드에서 직접 불러오려 했습니다.
하지만 두 가지 문제가 있었습니다.

  1. CORS 차단
    브라우저에서 바로 openapi.seoul.go.kr API를 호출하면 보안 정책 때문에 차단됨.
  2. API Key 노출
    발급받은 인증키를 그대로 프론트 코드에 넣으면, 배포 후 누구나 볼 수 있어 보안에 취약.

👉 그래서 프론트 → 프록시 서버(Express) → 공공데이터 API 구조로 바꾸었습니다.
프록시가 대신 API를 호출하고, 응답을 JSON으로 정리해 프론트로 전달하는 방식입니다.


2️⃣ 문제 원인

프록시 구조를 적용하니 로컬에서는 잘 됐지만,
Vercel에 배포했을 때는 이런 문제가 생겼습니다.

  • Timeout 발생 : 프론트에서 API를 직접 때릴 때 응답을 못 받음
  • 404 Not Found : Vercel 배포 후 /api/seoul/trades 경로를 찾지 못함
  • @vercel/node 타입 오류 : 서버리스 함수에서 타입을 잘못 import해 빌드가 막힘

원인을 정리하면:

  • 브라우저 직접 호출 → CORS + Key 노출
  • Vercel 배포 → Express 서버 자체는 지원하지 않고, 서버리스 함수 단위로 배포해야 함
  • 타입 선언 → 런타임에는 필요 없는 @vercel/node를 import해서 에러 발생

3️⃣ 해결 방법

✅ 프록시 서버 (로컬 개발용)

개발 중에는 Express로 프록시 서버를 열어두고, vite.config.ts에서 /api 요청을 프록시로 넘기도록 설정했습니다.

 
app.get('/api/seoul/trades', async (req, res) => {
  const { page, size, rcptYr, cggCd } = req.query;
  const url = `http://openapi.seoul.go.kr:8088/${process.env.SEOUL_SERVICE_KEY}/json/tbLnOpendataRtmsV/1/10/${rcptYr}/${cggCd}/`;
  const { data } = await axios.get(url);
  res.json(data);
});

 

✅ 서버리스 함수 (배포용)

Vercel은 Express 서버를 그대로 올릴 수 없으므로,
api/seoul/trades.ts 파일을 만들어 개별 함수로 배포했습니다.

export default async function handler(req: any, res: any) {
  const { page = 1, size = 10, rcptYr, cggCd } = req.query;
  const start = (Number(page) - 1) * Number(size) + 1;
  const end = Number(page) * Number(size);

  const url = `http://openapi.seoul.go.kr:8088/${process.env.SEOUL_SERVICE_KEY}/json/tbLnOpendataRtmsV/${start}/${end}/${rcptYr}/${cggCd}/`;

  try {
    const { data } = await axios.get(url, { timeout: 20000 });
    res.status(200).json(data);
  } catch (e: any) {
    res.status(500).json({ message: 'Seoul API 호출 실패', detail: e.message });
  }
}

 

4️⃣ 배운 점

배포 환경 차이, 서버리스 구조의 한계까지 이해할 수 있었습니다.
이후에는 axios 요청에 타임아웃 로직을 추가하고,
Vercel Edge Cache를 활용해 응답 속도와 안정성을 높였습니다.