본문으로 건너뛰기
오토프로그 홈

13강: API 연동

v5
작성 2026-04-12읽는 시간 11

외부 서비스 붙이기

이번엔 남의 데이터를 가져다 쓸 차례예요

12강에서 Supabase로 우리만의 창고(데이터베이스)를 만들었어요. 할 일 목록을 넣고, 읽고, 수정하고, 삭제하는 CRUD를 직접 해봤죠. 새로고침해도 데이터가 사라지지 않는 경험, 꽤 뿌듯했을 거예요.

그런데 생각해 보세요. 세상의 모든 데이터를 우리가 직접 만들 수 있을까요?

오늘 서울 날씨가 몇 도인지, 우리가 직접 측정할 수는 없어요. 지도 데이터를 처음부터 그릴 수도 없고요. AI가 글을 써주는 기능을 밑바닥부터 만드는 건 더더욱 불가능해요.

다행히, 이런 건 이미 누군가가 다 만들어놨어요. 우리는 그걸 가져다 쓰기만 하면 돼요. 어떻게요? API라는 주문 창구를 통해서요.


이건 뭐예요?

API = 식당 주문 창구

API(Application Programming Interface, 프로그램끼리 데이터를 주고받는 창구)를 식당에 비유해 볼게요.

여러분이 식당에 가면, 주방에 직접 들어가서 요리하지 않잖아요. 주문 창구(카운터)에서 메뉴를 보고, 주문하고, 음식을 받아요. 주방에서 뭘 어떻게 만드는지는 몰라도 돼요. 메뉴판만 읽을 줄 알면 되죠.

API도 완전히 같아요.

식당API
메뉴판API 문서 (어떤 데이터를 줄 수 있는지 목록)
주문서요청(Request, 내가 원하는 데이터를 적어 보내는 것)
음식응답(Response, 서버가 보내주는 데이터)
주방서버 (데이터를 처리하는 컴퓨터)
카운터 직원API 엔드포인트 (주문을 받는 주소)

날씨가 궁금하면 날씨 식당(OpenWeatherMap)에 주문하고, 지도가 필요하면 지도 식당(카카오 지도)에 주문하고, AI 답변이 필요하면 AI 식당(OpenAI)에 주문하는 거예요. 주방(서버)이 어떻게 돌아가는지는 전혀 몰라도 돼요.

HTTP 메서드 = 주문의 4가지 종류

식당에서 할 수 있는 행동이 정해져 있듯이, API에도 4가지 주문 방법이 있어요. 이걸 HTTP 메서드(HTTP Method, 서버에 요청하는 방식의 종류)라고 불러요.

HTTP 메서드식당 비유하는 일예시
GET메뉴판 보기데이터를 가져와요 (조회)서울 날씨 알려줘
POST새 주문하기새 데이터를 보내요 (생성)이 글을 번역해줘
PUT주문 변경하기기존 데이터를 바꿔요 (수정)배달 주소 바꿔줘
DELETE주문 취소하기데이터를 지워요 (삭제)이 주문 취소해줘

12강에서 배운 CRUD와 딱 맞아떨어지죠? Create = POST, Read = GET, Update = PUT, Delete = DELETE. 이름만 달라졌을 뿐, 하는 일은 같아요.

참고로 수정에는 PATCH라는 다섯 번째 메서드도 있어요. PUT은 주문서를 통째로 새로 쓰는 것, PATCH는 한 줄만 고치는 것이라고 보시면 돼요. 지금은 "수정은 PUT" 정도만 알아도 충분합니다.

실제로 우리가 가장 많이 쓰는 건 GET(데이터 가져오기)이에요. 날씨를 가져오거나, 뉴스를 가져오거나, 지도를 가져오는 건 전부 GET이에요.


우리는 이렇게 쓰고 있어요

오토프로그 랩스 사이트 자체는 정적 사이트(미리 만들어둔 파일을 보여주는 방식)라서 실시간 API 호출은 하지 않아요. 하지만 빌드 과정에서 API와 비슷한 원리를 쓰고 있어요.

예를 들어, 사이트 홈 화면에 "강의 12개", "레포 소개 8개" 같은 숫자가 자동으로 표시되죠? 이건 빌드할 때 docs/ 폴더를 스캔해서 파일 개수를 세는 코드가 돌아가는 거예요. 직접 숫자를 적는 게 아니라, "몇 개 있어?"라고 물어보고 답을 받는 구조예요. API의 원리와 같아요.

디온웍스의 다른 서비스들은 API를 아주 많이 써요.

  • DGHR(디지HR) — 카카오 로그인 API로 직원 인증, GPS API로 출퇴근 위치 확인, 카카오 알림톡 API로 근태 알림 발송
  • HoneyERP(허니이알피) — 사업자등록번호 조회 API로 거래처 정보 자동 입력, 택배사 배송 조회 API로 발주 상태 추적
  • D-onworks.com — 블로그 글이 등록되면 자동으로 메타 태그를 읽어서 카드를 생성. 이것도 URL에서 데이터를 가져오는 API 호출이에요

이 서비스들 전부, 처음에는 오늘 배울 것과 똑같이 시작했어요. 무료 API 하나를 골라서 데이터를 가져와 보는 것부터요.


한번 써볼까요?

오늘 실습은 두 단계로 나눠요.

  • 1단계: API 키 없이 쓸 수 있는 연습용 API(JSONPlaceholder)로 원리 익히기
  • 2단계: API 키가 필요한 진짜 API(OpenWeatherMap)로 날씨 데이터 가져오기

1단계: 연습용 API로 감 잡기 (JSONPlaceholder)

JSONPlaceholder는 연습용으로 만들어진 무료 가짜 데이터 API예요. 가입도 필요 없고, API 키도 필요 없어요. 브라우저 주소창에 URL만 입력하면 바로 데이터가 나와요.

브라우저 주소창에 이 주소를 붙여넣어 보세요.

https://jsonplaceholder.typicode.com/todos/1

이런 데이터가 보일 거예요.

{
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
}

축하해요. 방금 첫 번째 API 호출을 하신 거예요. 브라우저가 JSONPlaceholder 서버(식당 주방)에 GET 요청(메뉴판 보기)을 보내고, 서버가 할 일 데이터(음식)를 돌려준 거예요.

다른 주소도 시도해 보세요.

URL무슨 데이터?
https://jsonplaceholder.typicode.com/posts게시글 100개
https://jsonplaceholder.typicode.com/users사용자 10명
https://jsonplaceholder.typicode.com/photos?albumId=11번 앨범의 사진 목록

전부 GET 요청이에요. "이 데이터 줘"라고 주문하면, 서버가 JSON(JavaScript Object Notation, 데이터를 주고받을 때 쓰는 텍스트 형식) 형태로 보내주는 거예요.

2단계: 진짜 API로 날씨 가져오기 (OpenWeatherMap)

이번에는 진짜 날씨 데이터를 가져와 볼 거예요. OpenWeatherMap은 전 세계 날씨 데이터를 제공하는 서비스예요. 무료 플랜으로 충분히 실습할 수 있어요.

가입 + API 키 발급

  1. https://home.openweathermap.org/users/sign_up 에서 회원가입해요
  2. 이메일 인증을 완료해요
  3. 로그인 후 상단 메뉴에서 API keys 를 클릭하면, 기본 키가 하나 만들어져 있어요
  4. 이 키를 복사해 두세요 (발급 후 활성화까지 최대 2시간 걸릴 수 있어요)

브라우저에서 테스트

API 키가 활성화되면, 브라우저 주소창에 이렇게 입력해 보세요. YOUR_API_KEY 부분을 아까 복사한 키로 바꿔야 해요.

https://api.openweathermap.org/data/2.5/weather?lat=37.5665&lon=126.9780&appid=YOUR_API_KEY&units=metric&lang=kr
  • lat=37.5665&lon=126.9780 — 서울의 위도(lat)와 경도(lon)예요
  • appid=YOUR_API_KEY — 여러분의 API 키예요
  • units=metric — 섭씨 온도로 보여달라는 옵션이에요
  • lang=kr — 날씨 설명을 한국어로 보여달라는 옵션이에요

서울의 현재 날씨가 JSON 형태로 돌아와요. 온도, 습도, 바람 속도, 날씨 설명까지 전부요.

참고로 무료 플랜은 분당 60회, 월 100만 회까지 쓸 수 있어요. 실습에는 넘칠 만큼 넉넉하니 요금 걱정은 안 하셔도 됩니다.

API 키 안전하게 보관하기 (.env 복습)

12강에서 Supabase 키를 .env.local 파일에 넣었던 거 기억하시죠? API 키도 같은 파일에 넣어요. 코드에 직접 쓰면 안 돼요. GitHub에 올리면 전 세계에 내 키가 공개되니까요.

# .env.local — API 키 보관 (GitHub에 올라가지 않아요)
NEXT_PUBLIC_SUPABASE_URL=이전에_넣어둔_값
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=이전에_넣어둔_값
WEATHER_API_KEY=여기에_OpenWeatherMap_키를_붙여넣으세요

12강에서 만든 .env.local 파일에 한 줄만 추가하면 돼요. 파일을 새로 만들 필요 없어요.

그런데 이름을 자세히 보세요. 위의 두 줄에는 NEXT_PUBLIC_이 붙어 있는데, 오늘 추가한 날씨 키에는 안 붙어 있죠? 이게 아주 중요해요.

NEXT_PUBLIC_은 Next.js에게 "이 값은 브라우저에도 보내줘" 라고 말하는 표시예요. 이 표시가 붙으면 값이 웹페이지 안에 그대로 박혀서, 누구나 브라우저에서 꺼내 볼 수 있어요. .env.local 파일에 적었다고 안전해지는 게 아니에요. 그 파일은 GitHub에 안 올라가게 막아줄 뿐이에요.

  • Supabase의 공개용 열쇠(PUBLISHABLE_KEY, sb_publishable_…)는 원래 브라우저에 공개해도 되게 설계된 열쇠예요. 12강에서 배웠듯 허용된 동작만 할 수 있는 제한된 열쇠라, NEXT_PUBLIC_을 붙이는 게 맞아요.
  • 반면 OpenWeatherMap 키는 공개하면 안 되는 열쇠예요. 남이 내 키로 실컷 호출하면 내 사용량이 깎이니까요. 그래서 NEXT_PUBLIC_일부러 안 붙였어요.

⚠️ API 키를 받으면 습관적으로 NEXT_PUBLIC_을 붙이는 실수가 정말 흔해요. 접두사를 붙이는 순간 그 키는 공개된 것이라고 생각하세요.

접두사를 안 붙이면, 브라우저는 어떻게 날씨를 가져오나요?

좋은 질문이에요. NEXT_PUBLIC_이 없으면 브라우저는 그 키를 볼 수 없어요. 그럼 브라우저에서 직접 OpenWeatherMap에 주문할 수가 없죠.

그래서 우리 가게 안에 직원을 한 명 두는 방식을 씁니다.

누가하는 일키를 아나요?
내 웹페이지 (브라우저)우리 직원에게 "날씨 좀 알아봐"❌ 몰라요
서버 라우트 (내 서버)키를 꺼내서 날씨 식당에 주문✅ 알아요
OpenWeatherMap (남의 서버)날씨 데이터를 돌려줌

손님(브라우저)은 멤버십 카드를 안 들고 있어도 돼요. 계산대 뒤에 있는 직원이 대신 카드를 내밀고 주문해 오니까요. Next.js에서는 이 직원을 라우트 핸들러(Route Handler, 내 서버에서 도는 작은 API)라고 부르고, app/api/weather/route.ts 같은 파일 하나로 만들어요.

복잡해 보이지만 걱정 마세요. 파일 두 개를 만들어 달라고 부탁하면 Claude가 알아서 다 해줍니다.

프로젝트에 날씨 데이터 연결하기

11강에서 만든 Next.js 프로젝트에 날씨 페이지를 추가할 거예요. API를 호출할 때는 JavaScript의 fetch(패치, 데이터를 가져오는 내장 함수)를 써요. 별도 설치가 필요 없어요. 이미 들어있거든요.

// fetch의 기본 구조 — 이건 외울 필요 없어요. Claude가 만들어줘요.
// 이 코드는 브라우저가 아니라 '서버 라우트' 파일 안에서 돕니다.
const apiKey = process.env.WEATHER_API_KEY // 서버에서만 읽히는 값
const response = await fetch(`https://api.openweathermap.org/data/2.5/weather?lat=37.5665&lon=126.9780&appid=${apiKey}&units=metric&lang=kr`)
const data = await response.json()
// data.main.temp → 현재 온도
// data.weather[0].description → 날씨 설명 (예: "맑음")

fetch는 식당에 주문서를 보내는 행위예요. await(어웨이트, 응답이 올 때까지 기다리기)를 붙이는 이유는, 주문하고 음식이 나올 때까지 기다려야 하니까요. 주문하자마자 바로 음식이 나오진 않잖아요.


클로드 코드 터미널에서는 이렇게

11강에서 만든 Next.js 프로젝트에 날씨 페이지를 추가하는 전체 흐름이에요.

# ── 1. 프로젝트 폴더로 이동 (일반 터미널에서) ──
cd ~/my-service

# ── 2. Claude Code 시작 ──
claude

Claude Code가 열리면, 먼저 연습용 API로 감을 잡아볼게요.

클로드 코드 대화창에서 !를 맨 앞에 붙이면 터미널 명령어를 바로 실행할 수 있어요. 결과가 나오면 클로드가 한마디 덧붙여 주기도 해요. 단, !는 터미널에서 연 클로드 코드에서만 되고, VS Code 확장 프로그램의 채팅 창에서는 안 돼요.

# ── 3. 연습용 API 테스트 (대화창에서 바로 실행) ──
! curl https://jsonplaceholder.typicode.com/todos/1

JSON 데이터가 터미널에 출력되면 성공이에요. 이제 Claude에게 날씨 페이지를 만들어 달라고 해요.

너는 10년차 풀스택 개발자야.
나는 코딩 1줄도 모르는 바이브 코더야.

OpenWeatherMap API로 서울 날씨를 보여주는 페이지를 만들어줘.

요구사항:
1. app/api/weather/route.ts에 서버 라우트를 만들어줘
- .env.local의 WEATHER_API_KEY를 process.env로 읽어서 OpenWeatherMap을 호출해
- API 키는 절대 브라우저로 내보내지 마. 응답에는 날씨 데이터만 담아줘
2. app/weather/page.tsx에 새 페이지를 만들어줘
- 이 페이지는 OpenWeatherMap이 아니라 우리 서버의 /api/weather를 호출해
3. 페이지를 열면 서울의 현재 날씨를 자동으로 가져와서 보여줘
4. 보여줄 정보: 현재 온도, 체감 온도, 날씨 설명(한국어), 습도, 바람 속도
5. 로딩 중일 때 "날씨 불러오는 중..." 표시
6. 에러가 나면 "날씨를 가져올 수 없어요" 메시지 표시

API 정보:
- 엔드포인트: https://api.openweathermap.org/data/2.5/weather
- 필수 파라미터: lat=37.5665, lon=126.9780, appid=API키, units=metric, lang=kr
- 응답에서 쓸 필드: main.temp, main.feels_like, main.humidity, weather[0].description, wind.speed

디자인:
- Tailwind CSS 사용
- 다크 배경, 밝은 글씨, 시안 포인트(#06b6d4)
- 카드 형태로 날씨 정보 표시
- 모바일 반응형

안 할 것:
- 다른 파일은 건드리지 마
- 외부 라이브러리 추가하지 마 (fetch는 내장 함수)
- 위치 자동 감지는 하지 마 (서울 고정)
- 환경 변수 이름에 NEXT_PUBLIC_ 접두사를 붙이지 마

코드에 한글 주석 달아줘.

11강에서 설치할 때 src/ 디렉터리를 쓰는 설정을 골랐다면, 위 경로 앞에 src/를 붙이면 돼요(src/app/api/weather/route.ts). 구조와 원리는 똑같습니다.

페이지가 만들어지면 확인해 보세요.

# ── 4. .env.local에 API 키 추가했는지 확인 ──
! cat .env.local

# ── 5. 개발 서버 실행 ──
! npm run dev

브라우저에서 http://localhost:3000/weather 를 열어보세요. 서울의 현재 날씨가 보이면 성공이에요.

이미 npm run dev가 돌고 있었다면, .env.local을 고친 뒤에는 껐다가 다시 켜야 새로 넣은 키를 읽어요. 개발 서버는 시작할 때 딱 한 번만 이 파일을 읽거든요.

좀 더 도전해 보고 싶다면, Claude에게 이렇게 시켜보세요.

weather 페이지에 도시 선택 기능을 추가해줘.

요구사항:
1. 서울, 부산, 제주 3개 도시 버튼을 추가해
2. 버튼을 누르면 해당 도시의 날씨로 전환
3. 페이지는 /api/weather?city=seoul 처럼 도시 이름만 넘기고,
위도/경도는 서버 라우트(route.ts) 안에서 골라 쓰게 해줘
4. 도시별 위도/경도 정보:
- 서울: lat=37.5665, lon=126.9780
- 부산: lat=35.1796, lon=129.0756
- 제주: lat=33.4996, lon=126.5312

안 할 것:
- weather 페이지와 서버 라우트 외의 파일은 건드리지 마
- 외부 라이브러리 추가하지 마
- API 키를 브라우저로 내보내지 마

잘 되면 커밋해 두세요.

# ── 6. 커밋 ──
! git add .
! git commit -m "날씨 API 연동 + 도시 선택 기능"

API 호출 코드가 실제로 뭘 하는 건지

Claude가 만들어준 route.ts 안에는 이런 패턴이 들어있을 거예요. 직접 쓸 필요는 없지만, 흐름을 알아두면 Claude에게 더 정확한 지시를 할 수 있어요.

// 0. 서버에서만 읽히는 키 꺼내기 (NEXT_PUBLIC_ 없음)
const apiKey = process.env.WEATHER_API_KEY

// 1. API에 주문(요청) 보내기
const response = await fetch(
`https://api.openweathermap.org/data/2.5/weather?lat=37.5665&lon=126.9780&appid=${apiKey}&units=metric&lang=kr`
)

// 2. 주문한 음식(응답)이 제대로 왔는지 확인
if (!response.ok) {
throw new Error('날씨를 가져올 수 없어요')
}

// 3. 음식(데이터)을 접시(변수)에 담기
const data = await response.json()

// 4. 접시에서 원하는 부분만 꺼내 쓰기
const temperature = data.main.temp // 현재 온도
const description = data.weather[0].description // "맑음", "흐림" 등
const humidity = data.main.humidity // 습도

패턴이 보이시죠?

  1. fetch(URL) — 식당(서버)에 주문을 보내요
  2. response.ok — 주문이 제대로 접수됐는지 확인해요
  3. response.json() — 음식(데이터)을 받아요
  4. data.원하는필드 — 음식에서 먹고 싶은 부분만 골라요

12강에서 Supabase 코드가 항상 supabase.from('테이블').동작() 패턴이었듯이, API 호출도 항상 fetch(URL) → 확인 → json() → 사용 패턴이에요. 구조를 외울 필요 없어요. Claude가 만들어줘요.


배포할 때 API 키는 어디에?

로컬(내 컴퓨터)에서는 .env.local 파일에 키를 넣으면 되지만, Vercel(16강에서 배울 배포 서비스)에 배포할 때는 어떻게 할까요?

Vercel 대시보드에서 프로젝트를 고른 뒤, 왼쪽 사이드바의 Environment Variables(환경 변수 설정) 메뉴에 같은 값을 넣어주면 돼요. .env.local 파일을 Vercel이 대신 관리해주는 거예요.

Key: WEATHER_API_KEY
Value: 여러분의_OpenWeatherMap_키

여기서도 NEXT_PUBLIC_은 붙이지 않아요. 서버 라우트가 읽을 값이니까요.

이건 16강(배포)에서 자세히 다룰 거예요. 지금은 "배포할 때도 API 키를 따로 설정해야 한다"는 것만 기억해 두세요.


이번 강에서 기억할 것

핵심만 정리해 볼게요.

  1. API는 식당 주문 창구예요. 주문(요청)을 보내면 음식(데이터)이 나와요. 주방(서버)이 어떻게 돌아가는지는 몰라도 돼요.

  2. HTTP 메서드는 4가지예요. GET(메뉴 보기 = 조회), POST(주문하기 = 생성), PUT(주문 변경 = 수정), DELETE(주문 취소 = 삭제). 가장 많이 쓰는 건 GET이에요.

  3. API 키는 식당 멤버십 카드예요. 누가 주문하는지 알려주는 열쇠예요. 코드에 직접 쓰면 안 되고, .env.local 파일에 보관해요.

  4. NEXT_PUBLIC_을 붙이면 그 키는 공개돼요. 브라우저까지 값이 그대로 전달되거든요. 남에게 보이면 안 되는 키는 접두사 없이 두고, 서버 라우트(app/api/.../route.ts)가 대신 주문하게 하세요.

  5. fetch는 주문서를 보내는 함수예요. fetch(URL)response.json()data.원하는필드 패턴만 기억하면 돼요. 실제 코드는 Claude가 만들어줘요.

  6. 혼자 다 만들 필요 없어요. 날씨는 OpenWeatherMap, 지도는 카카오 지도, AI는 OpenAI. 남이 만든 걸 API로 가져다 쓰면 돼요.

다음 강에서는 14강: 인증 — 로그인 만들기를 다뤄요. 지금은 누구나 모든 데이터를 볼 수 있잖아요? "이건 내 데이터니까 나만 볼 수 있게"를 만들려면, 먼저 누가 쓰고 있는지(로그인)를 알아야 해요. Supabase Auth로 이메일 로그인과 소셜 로그인을 만들어볼 거예요.


이런 분께 추천해요

API 연동은 "내 서비스에 남의 기능을 붙이고 싶은 분"을 위한 필수 단계예요.

  • 내 앱에 날씨, 뉴스, 환율 같은 실시간 정보를 보여주고 싶은 분 — 공개 API를 연결하면 돼요. 데이터를 직접 수집할 필요가 없어요.
  • 카카오 로그인, 구글 지도, 결제 같은 기능을 넣고 싶은 분 — 이런 기능은 전부 API로 제공돼요. 밑바닥부터 만드는 건 불가능에 가까워요.
  • ChatGPT나 Claude 같은 AI를 내 서비스에 넣고 싶은 분 — OpenAI API, Anthropic API를 연결하면 내 앱 안에서 AI가 답변해줘요.

참고 링크

개정 이력5
  • v52026-07-191~20강 공통으로 반복되던 `!` 셸 모드 안내 문구를 하나로 통일 — 실행 결과에 클로드가 한마디 덧붙인다는 현행 동작과, 터미널에서 연 클로드 코드에서만 되고 VS Code 확장 채팅 창에서는 안 된다는 조건을 추가
  • v42026-07-1912강 v2의 열쇠 이름과 어긋나 있던 부분 정정 — .env.local 예시의 NEXT_PUBLIC_SUPABASE_ANON_KEY를 NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY로, 본문의 "Supabase의 ANON_KEY" 서술도 공개용 열쇠(publishable)로 교체. 그대로 따라 하면 12강에서 만든 변수명과 달라져 Supabase 연결이 끊기던 문제
  • v32026-07-1911·12·14강 v2와 경로 표기 통일(src/ 미사용) — 라우트 핸들러·페이지 경로를 app/ 기준으로 변경하고 src/ 선택 시 보조 안내 한 줄 추가
  • v22026-07-19NEXT_PUBLIC_ 접두사를 붙인 API 키는 브라우저에 그대로 노출된다는 사실을 반영 — 키 이름에서 접두사를 빼고 서버 라우트 경유 패턴으로 실습·프롬프트·배포 절차를 수정. PUT/PATCH 구분 각주, OpenWeatherMap 무료 한도, Next.js 환경 변수 문서 링크 갱신
  • v12026-04-12초판