API는 프로그램들이 서로 통신하는 방식입니다. 하나는 요청하고 다른 하나는 응답합니다. 마켓플레이스의 예시를 통해 요청이 무엇으로 구성되는지, JSON 응답을 어떻게 읽는지, Claude Code가 외부 데이터 소스를 연결할 때 무엇을 확인해야 하는지 알아봅시다. 마지막에 FastAPI를 어디에서 만날 수 있는지 간단히 짚어 보겠습니다.

API가 무엇인지 간단하게

API(Application Programming Interface)는 프로그램 인터페이스입니다. 사용 가능한 작업과 이를 호출하는 규칙을 정의합니다. API는 개별 애플리케이션뿐만 아니라 라이브러리, 운영 체제, 브라우저에도 있습니다. 이를 통해 프로그램은 다른 프로그램이나 그 일부에게 무언가를 해달라고 요청하고 결과를 얻을 수 있습니다. 여기서는 주로 주소로 호출되는 네트워크 API에 대해 이야기합니다.

레스토랑을 생각해보세요. 고객으로서 여러분은 부엌으로 가서 요리사에게 요리 방법을 설명하지 않습니다. 대신 웨이터에게 메뉴에서 원하는 것을 말하고, 웨이터가 주문을 부엌에 전달하고, 완성된 요리를 가져옵니다. API는 웨이터입니다. 클라이언트 프로그램은 웨이터를 통해 주문하고, 부엌(다른 프로그램)이 그 주문을 처리합니다. 내부가 어떻게 작동하는지 알 필요가 없습니다. 메뉴를 알고 요청할 수 있는 것과 응답으로 받을 것을 이해하면 됩니다.

본질적으로 API는 계약입니다: "나에게는 이런 식으로 요청하면 되고, 그러면 이런 결과를 돌려준다".

Claude Code가 서비스 연결을 제안할 때는 무엇을 요청할 수 있고 응답으로 무엇이 오는지 먼저 파악해야 합니다. 이 "메뉴"를 설명하는 것이 API 문서입니다.

영어로 된 짧은 유머 영상도 있습니다: "How API work". 같은 생각을 그림으로 보여 줄 뿐, 주제를 설명하는 영상은 아닙니다. 필요한 내용은 모두 아래 본문에 있습니다.

마켓플레이스의 요청과 응답

공급업체가 자신의 프로그램에서 상품을 올리는 마켓플레이스를 떠올려 보세요. 웹사이트의 버튼으로 수천 개의 상품을 옮기는 것은 불편하므로, 마켓플레이스는 프로그램에서 호출할 수 있는 API 작업을 제공합니다. 예를 들어, POST /products는 상품을 추가하고 GET /reports는 보고서를 반환합니다.

사용 가능한 작업의 주소를 엔드포인트라고 합니다. 요청을 이해하려면 주소와 HTTP 메서드를 모두 봐야 합니다. GET /products와 POST /products는 다른 작업을 수행할 수 있습니다. GET은 일반적으로 데이터 읽기에, POST는 처리할 데이터를 보내는 데 사용됩니다.

데이터는 종종 JSON 형식으로 전송됩니다. 중괄호는 객체의 필드를 묶고, 문자열은 따옴표로 감싸며, 객체 목록은 대괄호 안에 씁니다:

{
  "name": "탁상 조명",
  "price": 15000,
  "count": 350
}

클라이언트가 요청을 전송하고 서버가 처리한 후 응답을 반환합니다. 아래는 완전한 HTTP 패킷이 아니라 요약된 교환 구조입니다:

POST /products
{ "name": "탁상 조명", "price": 15000, "count": 350 }

201 Created
{ "id": 4567, "status": "added" }

201 Created는 응답 상태 코드이고 아래 JSON은 결과를 포함한 본문입니다. 실제 API 문서에서는 엔드포인트, 메서드, 필수 매개변수, 헤더, 응답 형식 및 가능한 오류를 지정합니다. 전체 데이터 세트로 시작하는 것보다 하나의 테스트 객체로 시작하는 것이 더 안전합니다.

API는 계약입니다. Claude Code는 요청을 작성할 수 있지만, 코드가 계약에 맞는지는 최신 문서와 서비스의 실제 응답으로 확인합니다.

프론트엔드, 백엔드 및 그 사이의 API

API는 서로 다른 애플리케이션을 연결하기 위해서만 필요한 것이 아닙니다. 종종 하나의 애플리케이션은 내부적으로 두 개의 프로그램으로 구성되며, 이들도 API를 통해 통신합니다.

프론트엔드는 여러분이 브라우저에서 다루는 애플리케이션 부분입니다. 여기에는 버튼, 이미지, 메뉴, 양식 및 페이지 동작이 포함됩니다. 프로그램 로직은 일반적으로 JavaScript로 작성됩니다. 복잡한 계산을 직접 수행할 수도 있고, 데이터나 서버측 작업이 필요할 때 서버에 요청할 수도 있습니다.

백엔드는 애플리케이션의 서버 부분입니다. 결제를 처리하고, 주문을 저장하고, 액세스를 확인하고, 상품을 검색합니다. 개발 중에는 서버가 여러분의 컴퓨터에서 실행될 수 있고, 게시 후에는 호스팅에서 실행됩니다. 사용자는 페이지와 함께 서버의 소스 코드를 받지 않습니다. 브라우저는 요청에 대한 응답을 받습니다.

어떻게 통신할까요? 바로 같은 API를 통해서입니다. 백엔드는 외부 공급업체뿐만 아니라 자신의 프론트엔드에도 엔드포인트를 제공합니다:

  • 페이지를 열면 프론트엔드가 /products/list 엔드포인트를 호출하고, 백엔드가 상품 목록을 반환하고, 프론트엔드가 이를 보기 좋게 그립니다;
  • "구매" 버튼을 누르면 프론트엔드가 /orders 엔드포인트로 데이터를 보내고 백엔드가 주문을 처리합니다.
  • 브라우저에서의 동작
  • 프론트엔드 요청
  • 백엔드에서 처리
  • 데이터 응답

정리하면, API로는 서로 다른 애플리케이션끼리도, 한 애플리케이션의 부분끼리도 통신할 수 있습니다. 이 구조에서 브라우저는 요청을 보내고, 백엔드는 데이터를 처리해 결과를 반환합니다. 데이터베이스가 브라우저에서 직접 액세스 가능할 필요는 없습니다.

브라우저의 요청

위에서 프론트엔드가 백엔드의 "엔드포인트를 호출한다"고 말했습니다. 코드에서 어떻게 보이는지 봅시다. 브라우저에는 이를 위한 fetch 내장 함수가 있습니다. 필요한 주소로 HTTP 요청을 보내고 응답을 반환합니다. 응답 본문은 일반적으로 JSON으로 오며 .json() 메서드로 객체로 구문 분석됩니다.

로케일(언어와 지역 설정의 조합) 목록을 예로 들어 봅시다. 백엔드는 이미 /locales 주소에서 목록을 반환할 수 있고, 프론트엔드는 이를 화면에 보여 줘야 한다고 가정합시다. 예를 들어, 서버가 다음을 반환합니다:

[
  { "code": "en-GB", "language": "English", "country": "United Kingdom" },
  { "code": "de-DE", "language": "Deutsch", "country": "Germany" }
]

응답이 어떻게 오는지

아래 코드는 페이지 핸들러의 비동기 함수 안에서 실행되며 데이터를 받아 오는 부분까지만 보여 줍니다. 테이블 출력은 여기서 생략했습니다.

const res = await fetch("/locales");
if (!res.ok) {
  throw new Error(`HTTP ${res.status}`);
}
const locales = await res.json();
// 이제 locales에는 테이블용 데이터가 들어 있습니다

데이터를 읽기 전에 res.ok를 확인합니다. 404나 500 같은 HTTP 오류만으로는 fetch가 예외를 던지지 않습니다. 이와 별개로 네트워크 요청 자체가 실패하거나 JSON 구문 분석이 실패할 수도 있습니다. 이런 코드 조각에서 난 오류는 페이지 코드가 잡아서 사용자에게 알기 쉬운 메시지로 보여 줘야 합니다. 원인은 서로 다르지만, 사용자 입장에서는 어느 경우든 데이터를 받지 못한 것입니다. 자세한 내용은 MDN fetch 가이드를 참조하세요.

여기에는 놓치기 쉬운 작은 부분이 몇 가지 있습니다:

  • 기본적으로 fetch는 GET, 즉 데이터를 가져오는 요청을 보냅니다. 다른 작업은 메서드로 지정합니다. 예를 들어 우리 마켓플레이스는 POST를 통해 새 상품을 받습니다;
  • 주소 /locales는 상대 주소입니다. 일반 HTTP 페이지에서는 같은 origin의 루트를 참조합니다. Origin은 스킴, 호스트, 포트로 정해집니다. 서버에는 이 경로가 있어야 합니다;
  • fetch와 .json()은 즉시 결과를 반환하지 않으므로 앞에 await를 씁니다. "응답을 기다려라"는 의미입니다.

HTML을 file://를 통해 파일로 열면 /locales는 여러분의 HTTP 서버 주소를 가리키지 않습니다. 이 예제에서는 해당 경로가 구현된 서버를 통해 페이지를 엽니다. HTML 파일 자체는 이 경로를 만들지 않습니다.

프론트엔드와 API는 다른 origin에 있을 수 있습니다. 그러면 브라우저에서 응답을 읽으려면 API 서버가 CORS를 통해 필요한 액세스를 허용해야 합니다. 이것은 교차 출처 액세스를 위한 메커니즘이지, 아무 네트워크 오류에나 붙이는 이름이 아닙니다. 페이지와 API를 한 origin에 배치하면 예제가 단순화되지만 모든 애플리케이션에 필수는 아닙니다. 세부사항은 MDN의 CORS 설명을 참조하세요.

누가 브라우저에 응답하는가

fetch("/locales")에 응답하는 것은 누구일까요? 백엔드입니다. 그리고 꼭 Python과 FastAPI로 만들 필요는 없습니다. API는 프로그램 간의 약속일 뿐 특정 언어가 아닙니다. 같은 엔드포인트를 Node.js, Go 또는 Java로도 작성할 수 있습니다. 예를 들어 Node.js 서버 핸들러에서 준비된 배열 locales를 반환할 수 있습니다. 아래는 완전한 서버가 아니라 핸들러의 일부입니다:

// req와 res는 핸들러가 받았고 locales는 미리 준비되어 있습니다
if (req.method === "GET" && req.url === "/locales") {
  res.statusCode = 200;
  res.setHeader("Content-Type", "application/json; charset=utf-8");
  res.end(JSON.stringify(locales));
}

밖에서 보면 이것은 여전히 같은 HTTP 요청 GET /locales이고, 응답에는 상태 200과 JSON이 있습니다. 프론트엔드는 백엔드가 무엇으로 작성되었는지 알 필요가 없습니다. 주소, 요청 규칙 및 응답 형식만 필요합니다.

Claude Code가 fetch("/locales")를 작성하면 반대쪽도 보여 달라고 요청하세요. 이 요청에 어떤 코드가 응답하는지 에이전트가 짚어 주게 하세요. 그런 다음 응답이 오지 않을 때 사용자가 무엇을 보게 되는지 확인하세요.

API의 종류

API는 두 가지 특징으로 나누기 편합니다:

  • 로컬과 네트워크 - 예를 들어 라이브러리의 API는 프로그램 코드에서 호출되고, 네트워크 API는 네트워크를 통해 액세스됩니다. 공개 인터넷에 연결되지 않은 내부 네트워크일 수도 있습니다;
  • 공개와 내부 - 공개 API는 외부 개발자를 위해 설계되었고, 내부 API는 시스템의 일부를 연결합니다. 공개 API라도 등록, 결제, 권한을 요구할 수 있습니다.

웹 API는 종종 HTTP - 요청 및 응답 프로토콜을 사용합니다. 문서에서 만날 REST는 API를 구축하는 방법을 설명합니다. 모든 HTTP API가 자동으로 REST를 준수하는 것은 아닙니다. 지금은 응답에서 상태 코드를 읽는 것이 더 유용합니다:

  • 200 - 정상입니다;
  • 201 - 생성됨(예: POST 후의 새 객체);
  • 404 - 찾을 수 없음;
  • 401 - 요청에 적절한 인증 데이터가 없습니다;
  • 429 - 요청이 너무 많습니다;
  • 500 - 서버 내부 오류.

지금은 깊이 들어갈 필요가 없습니다. 요청과 응답을 주고받는다는 기본 개념을 잡는 것이 중요합니다. 우선은 이 정도면 충분합니다.

상태 코드를 외워야 할 필요는 없습니다. http.cat 웹사이트에서 각 HTTP 상태가 고양이 그림으로 표시됩니다.

서비스에 액세스 키가 필요한 이유

많은 서비스가 먼저 API 키, 즉 여러분의 계정이나 프로젝트에 연결된 문자열을 발급받으라고 요구합니다. 키는 문서에 적힌 방식대로 보내며, 흔히 요청 헤더에 담습니다. 서비스는 액세스를 확인하고 여러분이 보낸 요청 수를 집계할 수 있습니다. 다른 연동에서는 토큰이라는 말도 보게 됩니다. 유사한 목적을 가지고 있지만 얻는 방식, 유효 기간 및 권한이 다를 수 있습니다.

적절한 액세스가 없으면 요청이 실행되지 않습니다. 예를 들어 서버는 401로 응답할 수 있습니다. 요청 빈도를 초과하는 것은 종종 코드 429로 표시됩니다. 응답의 정확한 의미와 허용량은 해당 서비스의 문서에서 확인합니다. 키가 아예 필요 없는 공개 데이터 소스도 있습니다.

비밀 키는 부여된 권한 범위 안에서 액세스를 허용하며, 그 사용료가 여러분에게 청구되기도 합니다. 그래서 메신저 대화, 공개 코드, Git에 넣지 않습니다. 서버 쪽에서 프로세스 환경을 통해 값을 전달할 수 있습니다. 변수가 브라우저 JavaScript로 들어가면 비밀이 더 이상 숨겨지지 않습니다. 값을 설정할 위치와 프로그램에 전달하는 방법은 키와 환경 변수를 다루는 별도의 주제입니다.

준비된 API 찾기

지도, 날씨, 결제, 배송 같은 기능은 API를 통해 애플리케이션에 들어옵니다. 공개 문서가 있으면 연결하기 전에 서비스의 기능을 파악할 수 있습니다. 시작은 해결하려는 과제 자체에서 하는 것이 좋습니다. 어떤 데이터가 필요한지, 얼마나 자주 업데이트해야 하는지, 어떻게 사용할 것인지 정의하세요.

찾을 때는 API와 요청 예제를 모아 둔 카탈로그인 Postman Public API Network를 둘러보면 편합니다. 찾은 예제는 시작점일 뿐입니다. 주소, 형식, 액세스 및 제한은 모두 서비스 소유자의 공식 문서에 따라 확인해야 합니다.

FastAPI는 어디에 있는가

FastAPI는 Python에서 API와 웹 서버를 만들기 위한 프레임워크 중 하나입니다. 엔드포인트를 서버 코드에 연결하고, 요청을 받고, JSON 응답을 반환할 수 있습니다. FastAPI는 Python 백엔드를 직접 만들 때 필요합니다. 준비된 API를 사용하려면 배울 필요가 없습니다. 레벨 7에서는 이름을 알고 이 경계를 이해하는 것으로 충분합니다.

Claude Code와 함께 작동하는 방식

이 개념들을 사용하면 에이전트의 작업을 더 쉽게 평가할 수 있습니다. 에이전트는 다른 서비스의 API 문서를 읽거나, 클라이언트 요청을 작성하거나, 여러분의 API를 FastAPI로 만들 수 있습니다. 여러분에게 중요한 것은 요청부터 페이지에 보이는 데이터까지의 구체적인 경로를 보는 것입니다. 누가 요청을 보내고, 누가 응답하고, 응답은 어떻게 처리될까요?

예를 들어, 지진 레이더를 위해 USGS의 공개 GeoJSON 피드가 있습니다. 지난 한 시간의 목록 주소:

GET https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_hour.geojson

아래는 응답 구조의 작은 교육용 예이며, 허구의 이벤트와 축소된 필드 세트입니다. 이것은 현재 USGS 데이터가 아닙니다:

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": { "mag": 4.2, "place": "교육 지점" },
      "geometry": { "type": "Point", "coordinates": [-122.5, 38.0, 8.0] }
    }
  ]
}

features에는 이벤트 배열이 있습니다. 경로 features[0].properties.mag는 첫 번째 이벤트의 규모(magnitude)로 이어집니다. 인덱스 0은 배열의 첫 번째 요소를 의미합니다. 좌표는 "경도, 위도, 깊이(킬로미터)" 순서입니다. 에이전트는 규모로 점의 크기를, 좌표로 점의 위치를 정할 수 있습니다. 배열이 비어 있으면 첫 번째 요소가 없습니다. 규모가 null이면 알 수 없는 값이라는 뜻이지, 규모 0인 이벤트라는 뜻이 아닙니다.

이제 요청 후 무엇을 보여 줄지 정하면 됩니다:

무엇을 얻었는지무엇을 표시할지
이벤트가 있는 성공적인 응답현재 조회 결과. 새 이벤트가 요청할 때마다 생기는 것은 아니므로 이전 결과와 같을 수도 있습니다.
빈 배열이 있는 성공적인 응답선택한 시간 범위에 이벤트가 없습니다. 이전 포인트는 범위를 벗어났을 수 있으므로 현재 데이터처럼 표시하지 않습니다.
응답 받기 또는 읽기 오류실패 메시지. 마지막으로 성공한 스냅숏이 있으면 시각 표시와 최신 데이터가 아니라는 경고를 붙여 그대로 둘 수 있습니다. 스냅숏이 없으면 아직 표시할 것이 없습니다.

요청을 실행하는 동안 페이지는 로딩을 표시할 수 있습니다. 다양한 결과를 확인하려면 교육용 응답을 사용하면 편합니다. 실제 서비스 오류나 새로운 지진을 기다릴 필요가 없습니다.

이제 Claude Code에 주는 작업 지시는 이렇게 쓸 수 있습니다:

지정한 API의 데이터를 페이지에 연결하세요.
먼저 공식 문서를 확인하세요: 주소, 메서드,
응답 형식 및 액세스 조건. 어떤 필드를 사용하는지 보여 주세요.
로딩, 빈 목록 및 업데이트 오류를 처리하세요.
오류 후 이전 데이터를 쓴다면 그 사실을 페이지에 표시하세요.
비밀 키를 클라이언트 코드에 넣지 마세요.
결과를 확인하고 어떤 상태를 확인했는지 보고하세요.

작업이 끝나면 완성된 화면만 보지 말고 실제 요청과 확인 결과도 살펴보세요. 에이전트의 액세스와 페이지의 액세스는 따로 구별하세요. MCP는 Claude Code에 도구를 연결할 수 있지만, 배포된 애플리케이션에는 자체 연동이 필요합니다. 요청이 애플리케이션 자체에 구현되어 있다면, 에이전트 세션을 닫아도 사이트의 요청은 멈추지 않아야 합니다.