🤖

본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.

⚠️

본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.

이미지 로딩 중...

API Integration 도구 완벽 가이드 - 슬라이드 1/6
A

AI Generated

2025. 12. 27. · 4 Views

API Integration 도구 완벽 가이드

외부 API를 호출하고 통합하는 방법을 처음부터 차근차근 배워봅니다. REST API 호출부터 인증, Rate Limiting, 실전 GitHub API 활용까지 실무에서 바로 쓸 수 있는 내용을 담았습니다.


목차

  1. REST_API_호출
  2. 인증_처리
  3. Rate_Limiting
  4. GitHub_API_도구_실습
  5. 다양한_API_통합_실습

1. REST API 호출

김개발 씨는 오늘 처음으로 외부 서비스와 연동하는 작업을 맡았습니다. "날씨 정보를 가져와서 화면에 보여주세요"라는 간단한 요구사항이었는데, 막상 시작하려니 어디서부터 손을 대야 할지 막막했습니다.

API가 뭔지는 알겠는데, 어떻게 호출하는 걸까요?

REST API 호출은 인터넷을 통해 다른 서버에 데이터를 요청하고 받아오는 것입니다. 마치 식당에서 메뉴판을 보고 주문하면 음식이 나오는 것처럼, 정해진 규칙대로 요청하면 원하는 데이터를 받을 수 있습니다.

이것을 이해하면 전 세계 수많은 서비스의 데이터를 여러분의 애플리케이션에서 활용할 수 있습니다.

다음 코드를 살펴봅시다.

// REST API 호출의 기본 패턴
async function fetchUserData(userId: string) {
  // GET 요청으로 사용자 정보를 가져옵니다
  const response = await fetch(`https://api.example.com/users/${userId}`, {
    method: 'GET',
    headers: {
      'Content-Type': 'application/json',
      'Accept': 'application/json'
    }
  });

  // 응답 상태 확인 - 200번대가 성공입니다
  if (!response.ok) {
    throw new Error(`API 호출 실패: ${response.status}`);
  }

  // JSON 형태로 데이터를 파싱합니다
  const data = await response.json();
  return data;
}

김개발 씨는 입사 3개월 차 주니어 개발자입니다. 선배가 건넨 과제는 단순해 보였습니다.

외부 API에서 데이터를 가져오는 것. 하지만 막상 키보드에 손을 올리니 머릿속이 하얘졌습니다.

"API 호출이 처음이구나?" 옆자리 박시니어 씨가 다가왔습니다. "걱정 마, 생각보다 간단해." 그렇다면 REST API란 정확히 무엇일까요?

쉽게 비유하자면, REST API는 마치 식당의 주문 시스템과 같습니다. 손님이 메뉴판을 보고 "짜장면 하나요"라고 주문하면, 주방에서 요리를 만들어 가져다줍니다.

여기서 메뉴판이 바로 API 문서이고, 주문하는 행위가 API 호출, 음식이 나오는 것이 응답입니다. API가 없던 시절에는 어땠을까요?

개발자들은 필요한 데이터를 모두 직접 수집하고 관리해야 했습니다. 날씨 정보가 필요하면 기상청 데이터를 직접 크롤링하고, 지도가 필요하면 직접 지도 데이터를 구축해야 했습니다.

시간과 비용이 어마어마하게 들었습니다. 바로 이런 문제를 해결하기 위해 REST API가 등장했습니다.

REST API를 사용하면 전문 서비스가 제공하는 데이터를 간단한 HTTP 요청으로 받아올 수 있습니다. 구글 지도, 카카오 로그인, 날씨 정보 등 수많은 서비스를 여러분의 앱에 통합할 수 있게 된 것입니다.

위의 코드를 한 줄씩 살펴보겠습니다. 먼저 fetch 함수를 사용합니다.

이것이 HTTP 요청을 보내는 핵심 도구입니다. 첫 번째 인자로 URL을 전달하고, 두 번째 인자로 옵션 객체를 전달합니다.

**method: 'GET'**은 데이터를 조회하겠다는 의미입니다. headers 부분은 요청에 대한 추가 정보를 담습니다.

Content-Type과 Accept를 JSON으로 설정하면 "나는 JSON 형식으로 통신하겠다"라고 서버에 알리는 것입니다. response.ok는 응답이 성공인지 확인합니다.

HTTP 상태 코드가 200번대면 true, 그 외에는 false입니다. 실패했다면 에러를 던져 문제를 명확히 드러냅니다.

마지막으로 **response.json()**으로 응답 본문을 JavaScript 객체로 변환합니다. 이제 이 데이터를 마음대로 활용할 수 있습니다.

실제 현업에서는 어떻게 활용할까요? 쇼핑몰을 개발한다고 가정해봅시다.

배송 조회 기능을 만들 때 택배사 API를 호출하면 실시간 배송 현황을 보여줄 수 있습니다. 결제 기능은 PG사 API를 연동합니다.

이처럼 REST API는 현대 웹 개발의 핵심 연결고리입니다. 하지만 주의할 점도 있습니다.

초보 개발자들이 흔히 하는 실수는 에러 처리를 빼먹는 것입니다. 네트워크는 언제든 실패할 수 있습니다.

서버가 다운되거나, 인터넷 연결이 끊기거나, 요청 형식이 잘못될 수 있습니다. 항상 try-catch로 감싸고, 사용자에게 적절한 안내 메시지를 보여줘야 합니다.

다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨의 설명을 들은 김개발 씨는 고개를 끄덕였습니다.

"아, 그냥 정해진 주소로 요청을 보내면 되는 거군요!" REST API 호출을 제대로 이해하면 전 세계 수많은 서비스를 여러분의 애플리케이션에 연결할 수 있습니다. 오늘 배운 fetch 패턴을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - fetch는 Promise를 반환하므로 반드시 async/await 또는 then()으로 처리해야 합니다

  • 개발 중에는 브라우저의 네트워크 탭에서 요청과 응답을 확인하는 습관을 들이세요
  • API 문서를 꼼꼼히 읽는 것이 삽질을 줄이는 가장 빠른 방법입니다

2. 인증 처리

김개발 씨가 첫 번째 API 호출에 성공한 다음 날, 새로운 과제가 떨어졌습니다. 이번에는 사용자 정보를 가져오는 API였는데, 호출할 때마다 401 에러가 발생했습니다.

"인증이 필요한 API네요"라는 선배의 말에 김개발 씨는 또다시 멘붕에 빠졌습니다.

API 인증은 "당신이 누구인지 증명하는 것"입니다. 마치 회사 건물에 들어갈 때 사원증을 보여주는 것처럼, API 서버에 요청할 때도 자신이 허가받은 사용자임을 증명해야 합니다.

인증 없이는 민감한 데이터에 접근할 수 없습니다.

다음 코드를 살펴봅시다.

// API 인증의 세 가지 주요 방식
class ApiClient {
  private apiKey: string;
  private accessToken: string;

  // 1. API Key 방식 - 헤더에 키를 포함합니다
  async callWithApiKey(url: string) {
    return fetch(url, {
      headers: { 'X-API-Key': this.apiKey }
    });
  }

  // 2. Bearer Token 방식 - OAuth에서 주로 사용합니다
  async callWithBearerToken(url: string) {
    return fetch(url, {
      headers: { 'Authorization': `Bearer ${this.accessToken}` }
    });
  }

  // 3. Basic Auth 방식 - 아이디:비밀번호를 Base64로 인코딩합니다
  async callWithBasicAuth(url: string, username: string, password: string) {
    const credentials = btoa(`${username}:${password}`);
    return fetch(url, {
      headers: { 'Authorization': `Basic ${credentials}` }
    });
  }
}

김개발 씨는 어제의 성공에 들떠 있었습니다. API 호출이 이렇게 쉬운 거였어?

자신감이 생긴 김개발 씨는 오늘 과제도 금방 끝낼 수 있을 거라 생각했습니다. 하지만 현실은 달랐습니다.

분명 코드는 맞는 것 같은데, 서버는 차갑게 401 Unauthorized를 반환했습니다. "아, 이건 인증이 필요한 API야." 박시니어 씨가 화면을 보며 말했습니다.

"아무나 접근할 수 없게 막아둔 거지." 그렇다면 API 인증이란 무엇일까요? 쉽게 비유하자면, API 인증은 마치 회사 건물의 출입 시스템과 같습니다.

아무나 들어올 수 없도록 사원증을 확인하고, 권한에 따라 갈 수 있는 층이 다릅니다. API도 마찬가지로 "당신은 누구인가요?"를 확인하고, 그에 맞는 데이터만 제공합니다.

인증이 없으면 어떤 일이 벌어질까요? 누구나 다른 사람의 개인정보를 볼 수 있게 됩니다.

악의적인 사용자가 데이터를 마음대로 수정하거나 삭제할 수 있습니다. 서비스 전체가 위험에 빠지게 됩니다.

이런 이유로 중요한 API는 반드시 인증을 요구합니다. 인증 방식은 크게 세 가지가 있습니다.

첫 번째는 API Key 방식입니다. 서비스에 가입하면 고유한 키를 발급받고, 모든 요청에 이 키를 포함시킵니다.

가장 간단하지만, 키가 노출되면 위험합니다. 주로 서버 간 통신이나 공개 API에서 사용합니다.

두 번째는 Bearer Token 방식입니다. OAuth 2.0에서 주로 사용하며, 로그인하면 토큰을 받고 이 토큰으로 인증합니다.

토큰은 일정 시간이 지나면 만료되므로 API Key보다 안전합니다. 소셜 로그인을 연동할 때 많이 만나게 됩니다.

세 번째는 Basic Auth 방식입니다. 아이디와 비밀번호를 Base64로 인코딩해서 보내는 가장 전통적인 방식입니다.

구현은 쉽지만, HTTPS가 아니면 위험합니다. 요즘은 많이 사용하지 않지만, 레거시 시스템에서 종종 만납니다.

위의 코드에서 각 방식을 살펴봅시다. X-API-Key 헤더는 API 제공자가 정한 헤더 이름입니다.

서비스마다 다를 수 있으니 문서를 확인해야 합니다. Bearer 뒤에 공백 하나를 넣는 것이 중요합니다.

btoa 함수는 문자열을 Base64로 인코딩합니다. 실무에서 가장 많이 사용하는 것은 Bearer Token입니다.

예를 들어 카카오 로그인을 연동한다고 해봅시다. 사용자가 카카오로 로그인하면 Access Token을 받습니다.

이 토큰을 저장해두었다가 카카오 API를 호출할 때 Authorization 헤더에 담아 보냅니다. 하지만 주의할 점이 있습니다.

절대로 인증 정보를 코드에 직접 작성하면 안 됩니다. Git에 올라가면 전 세계에 공개되는 것입니다.

환경 변수나 시크릿 관리 도구를 사용해야 합니다. 또한 클라이언트 코드에는 중요한 키를 넣지 마세요.

브라우저 개발자 도구에서 누구나 볼 수 있습니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.

"그러니까 이 토큰을 헤더에 넣어서 보내면 되는 거죠?" 박시니어 씨가 고개를 끄덕였습니다. "정확해.

이제 401 에러는 안 볼 거야." API 인증을 이해하면 보안이 중요한 서비스도 안전하게 연동할 수 있습니다. 각 방식의 특징을 이해하고 상황에 맞게 선택하세요.

실전 팁

💡 - 인증 정보는 반드시 환경 변수로 관리하고, .env 파일은 .gitignore에 추가하세요

  • Access Token이 만료되면 Refresh Token으로 갱신하는 로직을 미리 구현해두세요
  • 인증 실패 시 자동으로 재로그인을 유도하는 UX를 고려하세요

3. Rate Limiting

김개발 씨의 날씨 앱이 드디어 완성되었습니다. 테스트 삼아 버튼을 연타해봤는데, 갑자기 API가 응답을 멈췄습니다.

콘솔을 확인하니 429 Too Many Requests라는 낯선 에러가 보였습니다. "API를 너무 많이 호출한 거야." 선배의 한마디에 김개발 씨는 당황했습니다.

Rate Limiting은 일정 시간 내에 API를 호출할 수 있는 횟수를 제한하는 것입니다. 마치 놀이공원에서 인기 놀이기구의 탑승 인원을 제한하는 것처럼, 서버가 과부하되지 않도록 보호하는 장치입니다.

이 제한을 이해하고 적절히 대응해야 안정적인 서비스를 만들 수 있습니다.

다음 코드를 살펴봅시다.

// Rate Limiting에 대응하는 API 클라이언트
class RateLimitedApiClient {
  private requestQueue: Array<() => Promise<any>> = [];
  private isProcessing = false;

  // 요청 간 딜레이를 주어 Rate Limit을 피합니다
  async fetchWithRateLimit(url: string, delayMs: number = 100) {
    return new Promise((resolve, reject) => {
      this.requestQueue.push(async () => {
        try {
          const response = await fetch(url);

          // 429 에러 시 Retry-After 헤더를 확인합니다
          if (response.status === 429) {
            const retryAfter = response.headers.get('Retry-After') || '60';
            throw new Error(`Rate limited. Retry after ${retryAfter} seconds`);
          }

          resolve(await response.json());
        } catch (error) {
          reject(error);
        }
      });

      this.processQueue(delayMs);
    });
  }

  private async processQueue(delayMs: number) {
    if (this.isProcessing) return;
    this.isProcessing = true;

    while (this.requestQueue.length > 0) {
      const request = this.requestQueue.shift();
      await request?.();
      await new Promise(resolve => setTimeout(resolve, delayMs));
    }

    this.isProcessing = false;
  }
}

김개발 씨는 자신만만했습니다. 날씨 앱이 완성되었고, 기능도 잘 동작했습니다.

동료들에게 자랑하고 싶어서 새로고침 버튼을 연타했습니다. 딸깍딸깍딸깍.

갑자기 화면에 에러가 떴습니다. 429 Too Many Requests.

뭐지? 분명 몇 초 전까지 잘 됐는데?

"Rate Limit에 걸린 거야." 박시니어 씨가 화면을 보며 말했습니다. "API를 너무 자주 호출하면 서버가 차단해버려." 그렇다면 Rate Limiting이란 무엇일까요?

쉽게 비유하자면, Rate Limiting은 마치 은행 창구와 같습니다. 창구 직원은 한 번에 한 명의 고객만 응대할 수 있습니다.

만약 수백 명이 동시에 몰려들면 업무가 마비됩니다. 그래서 번호표를 뽑고 순서대로 처리하도록 합니다.

API 서버도 마찬가지입니다. Rate Limiting이 없으면 어떻게 될까요?

악의적인 사용자가 초당 수만 건의 요청을 보내면 서버가 다운됩니다. 모든 사용자가 피해를 봅니다.

이런 공격을 DDoS라고 하는데, Rate Limiting은 이를 방어하는 첫 번째 관문입니다. 일반적으로 API 제공자는 호출 제한을 정해둡니다.

예를 들어 "분당 100회" 또는 "일일 10,000회" 같은 식입니다. 이 제한을 초과하면 429 에러를 반환하고, 일정 시간이 지나야 다시 호출할 수 있습니다.

무료 플랜은 제한이 적고, 유료 플랜은 제한이 느슨합니다. 응답 헤더에서 Rate Limit 정보를 확인할 수 있습니다.

X-RateLimit-Limit은 최대 호출 횟수, X-RateLimit-Remaining은 남은 횟수, X-RateLimit-Reset은 제한이 초기화되는 시간입니다. 이 정보를 활용하면 429 에러를 미리 피할 수 있습니다.

위의 코드에서 핵심은 요청 큐입니다. 모든 요청을 큐에 넣고, 일정 간격으로 하나씩 처리합니다.

이렇게 하면 동시에 많은 요청을 보내는 것을 방지할 수 있습니다. 429 에러가 발생하면 Retry-After 헤더를 확인하여 그만큼 기다렸다가 재시도합니다.

실무에서는 더 정교한 전략을 사용합니다. Exponential Backoff라는 방식이 있습니다.

첫 번째 실패 시 1초 대기, 두 번째 실패 시 2초 대기, 세 번째 실패 시 4초 대기... 이런 식으로 대기 시간을 점점 늘립니다.

서버에 부담을 주지 않으면서 결국 성공할 수 있습니다. 캐싱도 좋은 전략입니다.

같은 데이터를 반복해서 요청할 필요가 없습니다. 한 번 받아온 데이터를 잠시 저장해두고 재사용하면 API 호출 횟수를 크게 줄일 수 있습니다.

사용자 경험도 좋아지고 비용도 절약됩니다. 하지만 주의할 점이 있습니다.

Rate Limit을 무시하고 계속 요청을 보내면, IP가 영구 차단될 수 있습니다. 또한 유료 API의 경우 호출 횟수에 따라 비용이 부과되므로, 불필요한 호출은 곧 돈 낭비입니다.

다시 김개발 씨의 이야기로 돌아가 봅시다. "그러니까 버튼을 연타하면 안 되는 거였군요..." 박시니어 씨가 웃으며 말했습니다.

"맞아. 사용자가 버튼을 아무리 눌러도 API 호출은 적절히 제한되도록 해야 해." Rate Limiting을 이해하면 안정적이고 효율적인 API 통합이 가능합니다.

항상 제한을 확인하고, 적절한 대응 전략을 준비해두세요.

실전 팁

💡 - API 문서에서 Rate Limit 정책을 반드시 확인하고 개발을 시작하세요

  • 디바운스(debounce)나 쓰로틀(throttle)로 사용자 입력에 의한 과도한 호출을 방지하세요
  • 중요한 API 호출은 실패 시 재시도 로직을 반드시 구현해두세요

4. GitHub API 도구 실습

어느 날 팀장님이 회의에서 말했습니다. "우리 프로젝트의 이슈 현황을 한눈에 볼 수 있는 대시보드를 만들어주세요." 김개발 씨는 GitHub API를 활용하면 되겠다고 생각했습니다.

하지만 실제로 어떻게 구현해야 할지 막막했습니다.

GitHub API는 GitHub의 거의 모든 기능을 프로그래밍으로 제어할 수 있게 해주는 강력한 도구입니다. 마치 GitHub 웹사이트에서 할 수 있는 모든 일을 코드로 자동화할 수 있는 것입니다.

이슈 관리, PR 조회, 저장소 정보 등 다양한 데이터를 가져올 수 있습니다.

다음 코드를 살펴봅시다.

// GitHub API를 활용한 실전 도구
class GitHubApiClient {
  private baseUrl = 'https://api.github.com';
  private token: string;

  constructor(token: string) {
    this.token = token;
  }

  // 공통 헤더 설정
  private getHeaders() {
    return {
      'Authorization': `Bearer ${this.token}`,
      'Accept': 'application/vnd.github.v3+json',
      'X-GitHub-Api-Version': '2022-11-28'
    };
  }

  // 저장소의 이슈 목록을 가져옵니다
  async getIssues(owner: string, repo: string, state: 'open' | 'closed' | 'all' = 'open') {
    const response = await fetch(
      `${this.baseUrl}/repos/${owner}/${repo}/issues?state=${state}`,
      { headers: this.getHeaders() }
    );
    return response.json();
  }

  // Pull Request 목록을 가져옵니다
  async getPullRequests(owner: string, repo: string) {
    const response = await fetch(
      `${this.baseUrl}/repos/${owner}/${repo}/pulls`,
      { headers: this.getHeaders() }
    );
    return response.json();
  }

  // 새 이슈를 생성합니다
  async createIssue(owner: string, repo: string, title: string, body: string) {
    const response = await fetch(
      `${this.baseUrl}/repos/${owner}/${repo}/issues`,
      {
        method: 'POST',
        headers: this.getHeaders(),
        body: JSON.stringify({ title, body })
      }
    );
    return response.json();
  }
}

김개발 씨는 팀장님의 요청을 듣고 잠시 생각에 잠겼습니다. GitHub에서 이슈 목록을 매번 수동으로 확인하는 건 번거롭습니다.

이걸 자동화할 수 있다면 팀 전체의 생산성이 올라갈 것입니다. "GitHub API를 써보는 게 어때?" 박시니어 씨가 제안했습니다.

"생각보다 잘 문서화되어 있어서 쓰기 편해." GitHub API는 무엇일까요? 쉽게 비유하자면, GitHub 웹사이트가 손으로 조작하는 리모컨이라면, GitHub API는 프로그래밍 가능한 스마트 리모컨입니다.

버튼을 누르는 대신 코드로 명령을 내릴 수 있습니다. 이슈 생성, PR 머지, 코드 검색 등 거의 모든 기능을 자동화할 수 있습니다.

GitHub API를 사용하려면 먼저 인증이 필요합니다. GitHub Settings에서 Personal Access Token을 발급받아야 합니다.

토큰을 발급받을 때 필요한 권한(scope)을 선택합니다. 예를 들어 이슈를 읽고 쓰려면 repo 권한이 필요합니다.

위의 코드에서 핵심을 살펴봅시다. getHeaders 메서드는 모든 요청에 공통으로 들어가는 헤더를 반환합니다.

Authorization에 토큰을 담고, Accept 헤더로 API 버전을 명시합니다. 이렇게 공통 로직을 분리하면 코드가 깔끔해집니다.

getIssues 메서드는 특정 저장소의 이슈 목록을 가져옵니다. owner는 GitHub 사용자명 또는 조직명, repo는 저장소 이름입니다.

state 파라미터로 열린 이슈, 닫힌 이슈, 전체 이슈를 필터링할 수 있습니다. createIssue 메서드는 새 이슈를 생성합니다.

POST 메서드를 사용하고, body에 JSON 데이터를 담아 보냅니다. 제목과 본문만 있으면 기본 이슈가 생성되고, labels, assignees 등 추가 옵션도 지정할 수 있습니다.

실무에서는 이런 식으로 활용합니다. 버그 리포트가 특정 채널에 들어오면 자동으로 GitHub 이슈를 생성합니다.

매일 아침 미해결 이슈 현황을 Slack으로 알립니다. PR이 머지되면 관련 이슈를 자동으로 닫습니다.

이런 자동화로 팀의 워크플로우가 훨씬 효율적이 됩니다. GitHub API의 Rate Limit도 알아두어야 합니다.

인증된 요청은 시간당 5,000회까지 가능합니다. 인증하지 않으면 시간당 60회밖에 안 됩니다.

많은 데이터를 가져와야 한다면 페이지네이션을 활용하고, 응답을 캐싱하는 것이 좋습니다. 에러 처리도 꼼꼼히 해야 합니다.

저장소가 private인데 권한이 없으면 404를 반환합니다. 토큰이 만료되면 401이 나옵니다.

Rate Limit에 걸리면 403을 반환합니다. 각 상황에 맞는 적절한 에러 메시지를 사용자에게 보여줘야 합니다.

다시 김개발 씨의 이야기로 돌아가 봅시다. 코드를 작성하고 테스트해보니, 팀 저장소의 이슈 목록이 깔끔하게 출력되었습니다.

"이걸로 대시보드를 만들면 되겠네요!" 김개발 씨의 눈이 반짝였습니다. GitHub API를 마스터하면 개발 워크플로우를 자동화하고, 팀 생산성을 크게 높일 수 있습니다.

공식 문서를 참고하며 다양한 엔드포인트를 탐험해보세요.

실전 팁

💡 - Personal Access Token은 반드시 환경 변수로 관리하고, 만료 기간을 설정해두세요

  • GitHub CLI(gh)도 같은 API를 사용하니, CLI로 먼저 테스트해보는 것도 좋습니다
  • Octokit 라이브러리를 사용하면 더 편리하게 GitHub API를 다룰 수 있습니다

5. 다양한 API 통합 실습

이제 김개발 씨는 자신감이 붙었습니다. GitHub API 연동에 성공하고 나니, 다른 API도 어렵지 않을 것 같았습니다.

팀장님이 새로운 요청을 했습니다. "날씨 API, 번역 API, 그리고 AI API까지 연동해서 스마트 알림 서비스를 만들어봐요." 이번에는 여러 API를 조합해야 합니다.

API 통합은 여러 외부 서비스를 하나의 애플리케이션에서 조화롭게 사용하는 것입니다. 마치 오케스트라에서 각 악기가 조화를 이루어 하나의 음악을 만들어내는 것처럼, 여러 API가 협력하여 더 강력한 기능을 제공합니다.

이 과정에서 통합 패턴과 에러 처리가 핵심입니다.

다음 코드를 살펴봅시다.

// 여러 API를 통합하는 서비스 클래스
class MultiApiIntegrationService {
  // 날씨 API 호출
  async getWeather(city: string): Promise<WeatherData> {
    const response = await fetch(
      `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${process.env.WEATHER_API_KEY}&units=metric`
    );
    if (!response.ok) throw new Error('날씨 정보를 가져올 수 없습니다');
    return response.json();
  }

  // 번역 API 호출
  async translate(text: string, targetLang: string): Promise<string> {
    const response = await fetch('https://api.deepl.com/v2/translate', {
      method: 'POST',
      headers: {
        'Authorization': `DeepL-Auth-Key ${process.env.DEEPL_API_KEY}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ text: [text], target_lang: targetLang })
    });
    const data = await response.json();
    return data.translations[0].text;
  }

  // 여러 API를 조합하여 스마트 알림 생성
  async generateSmartNotification(city: string, userLang: string) {
    try {
      // 병렬로 API 호출하여 성능 최적화
      const weather = await this.getWeather(city);
      const message = `${city}의 현재 기온은 ${weather.main.temp}도입니다.`;

      // 사용자 언어로 번역
      const translatedMessage = await this.translate(message, userLang);

      return { success: true, message: translatedMessage };
    } catch (error) {
      return { success: false, error: error.message };
    }
  }
}

interface WeatherData {
  main: { temp: number; humidity: number };
  weather: Array<{ description: string }>;
}

김개발 씨는 이제 더 큰 도전에 직면했습니다. 하나의 API를 호출하는 것은 익숙해졌지만, 여러 API를 엮어서 하나의 기능을 만드는 건 처음입니다.

마치 요리 재료를 각각 준비하는 것과 그것들을 조합해 요리를 완성하는 것의 차이와 같습니다. "API 통합은 퍼즐 맞추기 같아." 박시니어 씨가 설명을 시작했습니다.

"각 조각이 어떻게 맞물리는지 설계하는 게 중요해." API 통합이란 무엇일까요? 쉽게 비유하자면, API 통합은 마치 요리사가 여러 재료로 요리를 만드는 것과 같습니다.

신선한 채소(날씨 API), 좋은 양념(번역 API), 품질 좋은 고기(AI API)를 조합하여 맛있는 요리(스마트 서비스)를 완성합니다. 각 재료의 특성을 알고, 적절한 순서와 방법으로 조합해야 합니다.

API 통합에서 가장 중요한 것은 의존성 관리입니다. 어떤 API 호출이 다른 API 호출에 의존하는지 파악해야 합니다.

독립적인 호출은 병렬로 실행하여 시간을 절약하고, 의존적인 호출은 순차적으로 실행합니다. 위 코드에서는 날씨를 먼저 가져온 후 그 결과를 번역합니다.

에러 처리는 더욱 복잡해집니다. 하나의 API만 실패해도 전체 기능이 멈출 수 있습니다.

날씨 API가 실패하면 어떻게 할까요? 기본값을 보여줄지, 에러 메시지를 보여줄지, 캐시된 데이터를 사용할지 결정해야 합니다.

각 API별로 폴백(fallback) 전략을 세워두는 것이 좋습니다. 타임아웃 설정도 중요합니다.

외부 API는 언제든 느려질 수 있습니다. 하나의 API가 10초 이상 걸리면 사용자 경험이 나빠집니다.

각 API 호출에 적절한 타임아웃을 설정하고, 시간이 초과되면 대체 로직을 실행해야 합니다. 위 코드의 구조를 살펴봅시다.

각 API 호출을 별도의 메서드로 분리했습니다. 이렇게 하면 단일 책임 원칙을 지킬 수 있고, 테스트도 쉬워집니다.

날씨 API만 따로 테스트하고, 번역 API만 따로 테스트할 수 있습니다. generateSmartNotification 메서드가 통합의 핵심입니다.

여러 API를 순서대로 호출하고, 결과를 조합합니다. try-catch로 전체를 감싸서 어디서 에러가 나든 적절히 처리합니다.

실무에서는 서킷 브레이커(Circuit Breaker) 패턴을 적용합니다. 특정 API가 계속 실패하면, 일정 시간 동안 그 API 호출을 중단합니다.

마치 전기 회로의 차단기처럼, 문제가 있는 부분을 일시적으로 격리하여 전체 시스템을 보호합니다. 재시도(Retry) 로직도 필수입니다.

네트워크 일시적 오류로 실패할 수 있습니다. 한 번 실패했다고 바로 포기하지 말고, 몇 번 더 시도해봅니다.

단, 무한히 재시도하면 안 되고, 최대 횟수와 간격을 정해야 합니다. API 응답을 **정규화(normalize)**하는 것도 중요합니다.

각 API마다 응답 형식이 다릅니다. 어떤 API는 data.result에 결과가 있고, 어떤 API는 response.items에 있습니다.

이런 차이를 추상화하여 애플리케이션 코드에서는 일관된 형식으로 데이터를 다룰 수 있게 해야 합니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.

여러 API를 연동한 스마트 알림 서비스가 완성되었습니다. "와, 날씨 정보가 제 언어로 번역되어 나오네요!" 팀장님이 감탄했습니다.

김개발 씨의 첫 번째 실전 프로젝트가 성공적으로 마무리되었습니다. API 통합을 마스터하면 여러 서비스의 장점을 조합하여 더 강력한 애플리케이션을 만들 수 있습니다.

작은 기능부터 시작해서 점점 복잡한 통합에 도전해보세요.

실전 팁

💡 - 여러 API를 사용할 때는 각 API의 Rate Limit을 합산하여 고려해야 합니다

  • API 응답을 캐싱하면 비용과 속도 모두 개선할 수 있습니다
  • 통합 테스트 시에는 목(Mock) 서버를 활용하여 외부 의존성을 제거하세요

이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!

#API#REST#Integration#Authentication#RateLimiting#LLM,API,통합

댓글 (0)

댓글을 작성하려면 로그인이 필요합니다.

함께 보면 좋은 카드 뉴스