Showing posts with label devtools. Show all posts
Showing posts with label devtools. Show all posts

Thursday, March 24, 2022

"Postman에선 되는데 왜 내 코드에선 안될까?" 이 글 하나로 디버깅 시간 90% 줄이는 비법

"분명히 Postman으로 테스트했을 땐 완벽하게 동작했는데, 왜 내가 작성한 코드에서는 API 호출이 실패할까요?"

백엔드 API를 개발하거나 외부 API를 연동하는 개발자라면 누구나 한 번쯤은 이런 미스터리한 상황에 부딪혀본 경험이 있을 것입니다. Postman에서는 '200 OK'라는 반가운 응답이 오는데, 정작 내 애플리케이션 코드에서는 '400 Bad Request', '401 Unauthorized', '500 Internal Server Error' 등 절망적인 오류 메시지만을 마주하게 됩니다. 이럴 때면 개발자는 자신의 코드를 의심하고, 서버를 의심하고, 심지어는 네트워크 환경까지 의심하며 길고 긴 디버깅의 터널로 빠져들게 됩니다. 몇 시간, 때로는 며칠을 허비하기도 하죠.

하지만 이 문제의 해결책은 생각보다 훨씬 가까운 곳에, 바로 여러분이 성공적으로 요청을 보냈던 Postman 안에 숨겨져 있습니다. 이 글에서는 단순히 Postman의 기능 하나를 소개하는 것을 넘어, 'Postman에서는 되는데 내 코드에서는 안 되는' 고질적인 문제를 근본적으로 해결하고, 나아가 API 개발 및 테스트 생산성을 극적으로 향상시키는 Postman의 강력한 기능과 활용 전략을 심도 있게 파헤쳐 보겠습니다. 이 글을 끝까지 읽으신다면, 반복적인 API 디버깅에 쏟아붓던 시간을 90% 이상 단축하고 칼퇴를 보장하는 강력한 무기를 얻게 될 것입니다.

1. 문제의 근원: Postman과 당신의 코드는 무엇이 다른가?

문제를 해결하기 위해선 먼저 원인을 알아야 합니다. Postman과 당신의 코드가 동일한 API 엔드포인트에 요청을 보내는데 왜 결과가 다를까요? 그 이유는 우리가 미처 인지하지 못하는 '보이지 않는 차이' 때문입니다. 컴퓨터는 정직해서, 아주 작은 차이라도 있다면 다르게 반응합니다. 이 차이는 주로 다음과 같은 영역에서 발생합니다.

  • HTTP 헤더(Headers)의 차이: 가장 흔한 원인입니다. 브라우저나 Postman과 같은 클라이언트는 요청을 보낼 때 기본적으로 여러 헤더를 자동으로 포함시킵니다. 예를 들어, `Content-Type`, `Accept`, `User-Agent`, `Content-Length` 등이 있습니다. 특히 `Content-Type: application/json` 헤더는 POST나 PUT 요청 시 서버가 요청 본문(Body)을 어떻게 해석해야 할지 알려주는 매우 중요한 정보입니다. 개발자가 자신의 코드에서 이 헤더를 누락하면 서버는 요청을 제대로 파싱하지 못하고 오류를 반환할 수 있습니다.
  • 요청 본문(Body) 형식의 차이: JSON 데이터를 보낼 때, 객체를 그대로 보내는 것이 아니라 '문자열화(Stringify)'된 형태로 보내야 합니다. 많은 개발자들이 이 과정을 잊곤 합니다. 또한, `form-data`나 `x-www-form-urlencoded` 형식으로 데이터를 보내야 하는 API에 JSON 형식으로 보내는 등, 서버가 기대하는 데이터 형식과 다른 형식으로 요청을 보내는 경우도 비일비재합니다.
  • 인증(Authentication) 정보의 누락 또는 오류: Postman의 'Authorization' 탭에서 Bearer Token이나 API Key를 설정해두고, 정작 자신의 코드에서는 이 인증 정보를 헤더에 포함시키는 것을 잊는 경우가 많습니다. 혹은 토큰 값 앞뒤로 공백이 포함되거나, 'Bearer ' 접두사를 빠뜨리는 사소한 실수가 발생하기도 합니다.
  • 쿠키(Cookies)의 차이: Postman은 세션 기반 인증을 사용하는 API를 테스트할 때 자동으로 쿠키를 관리하고 후속 요청에 포함시켜 줍니다. 하지만 직접 작성한 코드에서는 이러한 쿠키 관리를 명시적으로 처리해주어야 합니다. 로그인 API 호출 후 받은 세션 쿠키를 다음 요청에 포함시키지 않으면, 서버는 해당 요청을 인증되지 않은 사용자의 요청으로 간주합니다.
  • URL 인코딩(Encoding) 문제: URL 파라미터(Query Parameter)에 한글이나 특수문자가 포함될 경우, 반드시 URL 인코딩을 거쳐야 합니다. 대부분의 HTTP 클라이언트 라이브러리는 이를 자동으로 처리해주지만, 특정 상황에서는 수동으로 처리해야 할 수도 있습니다. Postman은 이 과정을 매우 깔끔하게 처리해주기 때문에 차이가 발생할 수 있습니다.

이처럼 눈에 잘 보이지 않는 수많은 변수들이 존재하기 때문에, 단순히 "API 주소랑 데이터만 맞으면 되겠지"라고 생각하면 함정에 빠지기 쉽습니다. 그렇다면 이 모든 잠재적 차이점을 어떻게 확인하고 내 코드에 정확히 반영할 수 있을까요? 바로 여기에 Postman의 '코드 생성(Code Snippet)' 기능이 해결사로 등장합니다.

2. 디버깅의 치트키: Postman 코드 생성 기능 완벽 활용법

Postman의 코드 생성 기능은 Postman이 방금 서버로 보낸 '성공적인 요청'을 그대로 재현할 수 있는 코드를 다양한 프로그래밍 언어로 만들어주는 마법 같은 기능입니다. 즉, "성공이 보장된 모범 답안"을 제공하는 셈입니다. 이 기능을 활용하면, 내 코드와 Postman이 생성한 코드를 비교하며 '틀린 그림 찾기'를 하듯 문제의 원인을 정확하고 빠르게 찾아낼 수 있습니다.

2.1. 코드 생성 기능 사용하기 (Step-by-step)

사용법은 놀라울 정도로 간단합니다.

  1. 먼저, Postman에서 성공적인 API 요청을 보냅니다. 평소처럼 메소드(GET, POST 등), 주소, 파라미터, 헤더, 본문 등을 모두 설정하고 'Send' 버튼을 눌러 '200 OK'와 같은 성공 응답을 확인합니다.
  2. 화면 오른쪽의 '코드' 아이콘을 클릭합니다. 요청 URL 입력창 바로 아래, 'Send' 버튼 오른쪽에 있는 사이드바 메뉴에서 꺾쇠 괄호 모양의 아이콘( </> )을 찾을 수 있습니다. 이 아이콘이 바로 'Code' 버튼입니다.
Postman에서 코드 생성 버튼 위치를 보여주는 스크린샷

<그림 1: Postman의 코드 생성(</>) 버튼 위치>

  1. 원하는 언어와 라이브러리를 선택합니다. 'Code' 버튼을 클릭하면 새로운 창이 나타나며, 기본적으로 cURL 명령어 형태의 코드가 보입니다. 왼쪽 드롭다운 메뉴를 클릭하면 상상 이상으로 다양한 언어와 라이브러리 목록을 확인할 수 있습니다.
Postman이 지원하는 다양한 프로그래밍 언어 목록

<그림 2: JavaScript, Python, Java, C#, PHP 등 수많은 언어를 지원하는 Postman>

예를 들어, 프론트엔드 개발자라면 'JavaScript - Fetch', 백엔드 개발자라면 'Python - Requests', 'Java - OkHttp', 'Node.js - Axios' 등을 선택할 수 있습니다. 선택하는 즉시 해당 언어와 라이브러리에 맞는 코드가 자동으로 생성됩니다.

2.2. 생성된 코드 분석: 숨겨진 단서를 찾아라

이제 가장 중요한 단계입니다. 생성된 코드를 단순히 복사해서 붙여넣는 것에 그치지 말고, '분석'해야 합니다. 이 코드는 Postman이 성공적으로 요청을 보낼 수 있었던 모든 비밀을 담고 있습니다.

예를 들어, 사용자를 생성하는 POST API(`http://api.example.com/users`)를 호출하는 상황을 가정해 보겠습니다.

내 코드 (JavaScript - Fetch, 실패하는 경우)


const userData = {
    name: "홍길동",
    email: "gildong@example.com"
};

fetch('http://api.example.com/users', {
    method: 'POST',
    body: JSON.stringify(userData)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));

위 코드는 '400 Bad Request' 오류를 반환한다고 가정합시다. 이제 Postman에서 동일한 요청을 성공시킨 후, 'JavaScript - Fetch' 코드를 생성해 보겠습니다.

Postman이 생성한 코드 (JavaScript - Fetch, 성공 보장)


var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");
myHeaders.append("Authorization", "Bearer YOUR_ACCESS_TOKEN_HERE");
myHeaders.append("Accept", "*/*");
myHeaders.append("User-Agent", "PostmanRuntime/7.29.2");


var raw = JSON.stringify({
  "name": "홍길동",
  "email": "gildong@example.com"
});

var requestOptions = {
  method: 'POST',
  headers: myHeaders,
  body: raw,
  redirect: 'follow'
};

fetch("http://api.example.com/users", requestOptions)
  .then(response => response.text())
  .then(result => console.log(result))
  .catch(error => console.log('error', error));

두 코드를 비교해 보면 실패의 원인이 명확하게 드러납니다.

  • `Content-Type: application/json` 헤더 누락: 내 코드에는 이 헤더가 없습니다. 서버는 요청 본문이 어떤 형식인지 알 수 없어 제대로 파싱하지 못했을 가능성이 매우 높습니다. 이것이 '400 Bad Request'의 가장 유력한 원인입니다.
  • `Authorization` 헤더 누락: Postman 생성 코드에는 인증 토큰이 포함되어 있습니다. 만약 해당 API가 인증을 필요로 한다면, 이 헤더의 누락이 '401 Unauthorized' 오류의 원인이 됩니다.
  • 기타 헤더들 (`Accept`, `User-Agent`): 대부분의 경우 이 헤더들은 필수적이지 않지만, 일부 민감한 서버는 특정 `User-Agent`를 차단하거나 특정 `Accept` 타입만 허용할 수 있습니다. 만약 다른 문제를 모두 해결했는데도 오류가 발생한다면, 이 헤더들도 똑같이 추가하여 테스트해 볼 가치가 있습니다.

이처럼 Postman이 생성한 코드는 '정답지' 역할을 합니다. 내 코드와 한 줄 한 줄 비교하며 빠진 부분, 혹은 잘못된 부분을 찾아 수정하면 문제는 놀랍도록 쉽게 해결됩니다. 더 이상 막연한 추측으로 시간을 낭비할 필요가 없습니다.

3. 생산성을 폭발시키는 Postman 고급 활용 전략

코드 생성 기능으로 급한 불을 끄는 방법을 배웠다면, 이제는 한 걸음 더 나아가 Postman을 더욱 스마트하게 사용하여 애초에 버그 발생 가능성을 줄이고 개발 및 테스트 효율을 극대화하는 방법을 알아볼 차례입니다. Postman은 단순히 API 요청을 보내는 도구가 아니라, API 라이프사이클 전체를 관리할 수 있는 강력한 플랫폼입니다.

3.1. 변수와 환경(Variables & Environments): 반복 작업을 없애는 마법

API를 테스트하다 보면 반복적으로 입력하는 값들이 있습니다. API 서버의 기본 URL(`http://localhost:8080`, `https://dev-api.example.com`), 인증 토큰, 특정 사용자 ID 등이 대표적입니다. 개발 환경, 스테이징 환경, 운영 환경마다 이 값들이 달라지기 때문에 매번 수동으로 수정하는 것은 번거롭고 실수를 유발하기 쉽습니다.

환경(Environments)은 이러한 변수들을 그룹으로 묶어 관리할 수 있는 기능입니다. 예를 들어 'Local', 'Development', 'Production' 환경을 각각 만들고, 각 환경에 맞는 `baseUrl`과 `authToken` 변수를 설정할 수 있습니다.

  1. Postman 왼쪽의 'Environments' 탭을 클릭하고, '+' 버튼을 눌러 새 환경을 생성합니다. (예: 'My Project - Dev')
  2. VARIABLE 열에 `baseUrl`, INITIAL VALUE 열에 `https://dev-api.example.com`을 입력합니다.
  3. 마찬가지로 `authToken` 변수를 추가하고 개발용 토큰 값을 입력합니다.
  4. 요청 URL 입력창이나 헤더 값 입력창에 `{{baseUrl}}/users`, `Bearer {{authToken}}`과 같이 `{{변수명}}` 형식으로 변수를 사용합니다.
  5. Postman 우측 상단의 드롭다운 메뉴에서 내가 만든 환경('My Project - Dev')을 선택하면, `{{...}}` 부분들이 해당 환경에 설정된 값으로 자동 치환되어 요청이 전송됩니다.

이제 운영 서버를 테스트해야 한다면? 'My Project - Production' 환경을 선택하기만 하면 됩니다. 더 이상 URL이나 토큰을 일일이 복사해서 붙여넣을 필요가 없습니다. 이 기능 하나만으로도 작업 효율은 수직 상승합니다.

3.2. 컬렉션(Collections): API 명세서이자 자동화의 시작

컬렉션(Collections)은 관련 있는 API 요청들을 폴더 구조로 정리하고 관리하는 기능입니다. '사용자 관리 API', '상품 관리 API'처럼 기능 단위로 컬렉션을 만들고, 그 안에 '사용자 생성', '사용자 조회', '사용자 수정' 등의 개별 요청들을 저장할 수 있습니다.

잘 정리된 컬렉션은 그 자체로 훌륭한 API 명세서 역할을 합니다. 팀 동료는 컬렉션만 보고도 어떤 API들이 있고 어떻게 사용해야 하는지 쉽게 파악할 수 있습니다. 하지만 컬렉션의 진정한 힘은 'Collection Runner'에 있습니다.

Collection Runner는 컬렉션에 포함된 모든 요청을 한 번에, 또는 순차적으로 실행해주는 기능입니다. 이를 통해 전체 API 시스템의 통합 테스트(Integration Test)를 버튼 클릭 한 번으로 수행할 수 있습니다. 특정 기능 개발 후 기존 API들이 정상적으로 동작하는지 확인하는 회귀 테스트(Regression Test)도 손쉽게 자동화할 수 있습니다.

3.3. 테스트 스크립트(Tests): Postman을 자동화 테스트 툴로

Postman의 가장 강력한 기능 중 하나는 바로 'Tests' 탭입니다. 여기서는 API 요청이 완료된 '후에' 실행될 JavaScript 코드를 작성할 수 있습니다. 이를 통해 단순히 API가 호출되는 것을 넘어, 응답 결과가 우리가 기대한 대로 왔는지 자동으로 검증할 수 있습니다.

예를 들어, 사용자 정보를 조회하는 API를 테스트할 때 다음과 같은 스크립트를 작성할 수 있습니다.


// 1. 응답 상태 코드가 200 (OK)인지 검증
pm.test("Status code is 200", function () {
    pm.response.to.have.status(200);
});

// 2. 응답이 유효한 JSON 형식인지 검증
pm.test("Response is in JSON format", function () {
    pm.response.to.be.json;
});

// 3. 응답 JSON 본문에 'email'이라는 속성이 있는지 검증
pm.test("Response body has 'email' property", function () {
    const responseData = pm.response.json();
    pm.expect(responseData).to.have.property('email');
});

// 4. 응답된 email 값이 요청한 값과 일치하는지 검증
const requestedEmail = "gildong@example.com";
pm.test(`Email should be ${requestedEmail}`, function () {
    const responseData = pm.response.json();
    pm.expect(responseData.email).to.eql(requestedEmail);
});

// 5. 응답 시간을 검증 (예: 200ms 이내)
pm.test("Response time is less than 200ms", function () {
    pm.expect(pm.response.responseTime).to.be.below(200);
});

이러한 테스트 스크립트가 포함된 컬렉션을 Collection Runner로 실행하면, 수십 개의 API에 대한 수백 개의 검증 항목이 단 몇 초 만에 완료되고 그 결과가 깔끔한 보고서 형태로 제공됩니다. 이는 CI/CD 파이프라인과 연동하여 배포 전 API의 안정성을 자동으로 검증하는 수준까지 확장될 수 있습니다. 이제 Postman은 단순한 API 클라이언트가 아니라, 전문적인 자동화 테스트 도구로 진화합니다.

결론: 스마트한 개발자의 현명한 도구 사용법

"Postman에서는 되는데 내 코드에서는 안 된다"는 문제는 개발자에게 큰 좌절감을 안겨주는 흔한 난관입니다. 하지만 오늘 살펴본 것처럼, 이 문제의 해결책은 Postman의 '코드 생성' 기능 안에 명확하게 존재합니다. 성공한 요청의 '모범 답안'을 통해 내 코드의 문제점을 정확히 진단하고 수정함으로써, 우리는 디버깅에 낭비되는 소중한 시간을 획기적으로 줄일 수 있습니다.

그러나 여기서 멈춰서는 안 됩니다. 한 걸음 더 나아가 환경 변수를 활용해 반복적인 작업을 자동화하고, 컬렉션으로 API를 체계적으로 관리하며, 테스트 스크립트로 API의 안정성을 자동으로 검증하는 단계까지 나아가야 합니다. 이렇게 Postman을 단순한 HTTP 클라이언트가 아닌, API 개발의 전 과정을 아우르는 강력한 '플랫폼'으로 활용할 때, 우리의 개발 생산성과 코드의 품질은 이전과는 비교할 수 없는 수준으로 향상될 것입니다.

지금 당장 현재 진행 중인 프로젝트의 API를 Postman으로 테스트해 보십시오. 그리고 '코드 생성' 기능을 열어 당신의 코드와 비교해 보세요. 어쩌면 당신을 괴롭히던 버그의 원인이 허무할 정도로 간단한 헤더 하나, 혹은 작은 따옴표 하나의 차이였을지도 모릅니다. Postman을 현명하게 사용하는 것, 그것이 바로 스트레스 없는 API 개발과 칼퇴를 향한 가장 빠른 지름길입니다.

Tuesday, March 16, 2021

서버 구축 기다릴 필요 없어요! 프론트엔드 개발을 위한 필수 Mock API 총정리

프론트엔드 개발자라면 누구나 한 번쯤 겪어봤을 답답한 순간이 있습니다. 바로 백엔드 API 개발이 완료되기를 하염없이 기다리는 시간입니다. 디자인 시안은 완벽하게 나왔고, 컴포넌트 구조 설계도 끝났지만, 실제 데이터를 받아와 화면에 그려보는 핵심적인 작업을 진행할 수 없어 프로젝트 전체가 지연되는 경우입니다. 기획이 변경되거나 데이터베이스 스키마가 수정이라도 되면, 이 기다림의 시간은 기약 없이 길어지기도 합니다.

이러한 '의존성 지옥'에서 우리를 구출해 줄 강력한 도구가 바로 Mock API(가짜 API)입니다. Mock API는 실제 백엔드 서버가 구축되지 않았거나, 사용할 수 없는 상황에서 실제 API처럼 동작하는 가상의 API 엔드포인트를 제공하는 서비스입니다. 이를 통해 프론트엔드 개발자는 백엔드 개발 일정에 구애받지 않고 독립적으로 데이터 통신, UI 렌더링, 상태 관리 로직을 구현하고 테스트할 수 있습니다.

이번 글에서는 Mock API가 왜 현대 프론트엔드 개발의 필수 요소로 자리 잡았는지 알아보고, 가장 대표적이고 널리 사용되는 JSONPlaceholder를 중심으로 그 사용법을 A부터 Z까지 상세하게 파헤쳐 보겠습니다. 또한, JSONPlaceholder 외에도 특정 상황에서 유용하게 사용할 수 있는 다른 Mock API 서비스들을 함께 소개하여 여러분의 개발 생산성을 극대화할 수 있는 비법을 공유하고자 합니다.

Mock API, 왜 반드시 사용해야 할까?

단순히 '기다림의 시간을 줄여준다'는 것 외에 Mock API는 개발 워크플로우에 실질적인 여러 이점을 가져다줍니다.

  • 백엔드 개발 의존성 완전 탈피: 가장 큰 장점입니다. 프론트엔드와 백엔드 팀은 API 명세(Specification)만 사전에 합의하면 각자의 파트를 동시에 개발할 수 있습니다. 이는 프로젝트 전체 기간을 획기적으로 단축시키는 '병렬 개발'을 가능하게 합니다.
  • 신속한 프로토타이핑 및 UI/UX 검증: 디자인만 보고 구현하는 것을 넘어, 실제 데이터가 채워졌을 때의 화면을 미리 구현하고 테스트할 수 있습니다. 텍스트가 너무 길어질 때 UI가 깨지는지, 로딩 상태는 어떻게 보여줄지, 에러 발생 시 사용자에게 어떤 피드백을 줄지 등 다양한 엣지 케이스를 조기에 발견하고 개선할 수 있습니다.
  • 안정적이고 예측 가능한 테스트 환경: 실제 개발 중인 백엔드 API는 불안정할 수 있습니다. 버그로 인해 서버가 다운되거나, 데이터가 수시로 변경되어 프론트엔드 테스트에 일관성을 해칠 수 있습니다. Mock API는 항상 약속된 데이터를 정해진 형태로 반환하므로, 오롯이 프론트엔드 로직의 문제점을 찾는 데에만 집중할 수 있는 안정적인 환경을 제공합니다.
  • 비용 및 시간 절감: 실제 API를 호출하며 테스트하는 것은 네트워크 비용과 서버 리소스를 소모합니다. 특히 외부 유료 API를 사용하는 경우, 테스트를 위한 호출 하나하나가 모두 비용으로 직결될 수 있습니다. Mock API를 사용하면 이러한 비용 없이 무제한으로 테스트를 진행할 수 있습니다.

이제 Mock API의 필요성을 충분히 인지했다면, 가장 쉽고 강력한 도구인 JSONPlaceholder를 통해 실전에 돌입해 보겠습니다.

세상에서 가장 유명한 Mock API: JSONPlaceholder 완전 분석

JSONPlaceholder는 "Fake Online REST API for Testing and Prototyping"이라는 슬로건을 내걸고 있는, 명실상부 가장 대표적인 Mock API 서비스입니다. 별도의 회원가입이나 인증 절차 없이 즉시 사용할 수 있으며, RESTful API의 기본적인 구조와 HTTP 메서드를 연습하기에 최적화되어 있습니다.

1. JSONPlaceholder가 제공하는 핵심 리소스

JSONPlaceholder는 실제 블로그나 소셜 미디어 애플리케이션에서 흔히 볼 수 있는 데이터 모델을 기반으로 한 6가지의 기본 리소스(Resource)를 제공합니다. 각 리소스는 복수형 명사를 사용하여 RESTful 원칙을 잘 따르고 있습니다.

  • /posts: 게시물 데이터 (총 100개)
  • /comments: 댓글 데이터 (총 500개)
  • /albums: 앨범 데이터 (총 100개)
  • /photos: 사진 데이터 (총 5000개)
  • /todos: 할 일 목록 데이터 (총 200개)
  • /users: 사용자 데이터 (총 10개)

이 리소스들은 서로 관계를 맺고 있어, 실제 애플리케이션과 유사한 복합적인 데이터 호출 시나리오를 테스트해볼 수 있습니다. 예를 들어, 특정 사용자가 작성한 모든 게시물을 가져오거나, 특정 게시물에 달린 모든 댓글을 조회하는 것이 가능합니다.

2. HTTP 메서드별 사용법 완벽 정복

RESTful API의 핵심은 '자원(Resource)''행위(Verb)'로 다루는 것입니다. 여기서 행위에 해당하는 것이 바로 HTTP 메서드입니다. JSONPlaceholder는 주요 HTTP 메서드인 GET, POST, PUT, PATCH, DELETE를 모두 지원하며, 이를 통해 데이터 조회, 생성, 수정, 삭제(CRUD) 작업을 시뮬레이션할 수 있습니다.

A. GET: 데이터 조회하기 (Read)

GET은 서버로부터 데이터를 가져올 때 사용하는 가장 기본적인 메서드입니다. JSONPlaceholder를 활용한 다양한 GET 요청 시나리오를 살펴봅시다.

- 모든 리소스 목록 조회

가장 간단한 형태로, 특정 리소스의 모든 데이터를 배열 형태로 받아옵니다. 예를 들어 모든 게시물 목록을 가져오고 싶다면 /posts 엔드포인트로 GET 요청을 보내면 됩니다.


# curl을 이용한 요청
curl https://jsonplaceholder.typicode.com/posts

자바스크립트의 fetch API를 사용하면 다음과 같이 코드를 작성할 수 있습니다.


fetch('https://jsonplaceholder.typicode.com/posts')
  .then(response => {
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    return response.json();
  })
  .then(posts => {
    console.log('전체 게시물 수:', posts.length); // 100
    console.log('첫 번째 게시물:', posts[0]);
    // {
    //   "userId": 1,
    //   "id": 1,
    //   "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
    //   "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
    // }
  })
  .catch(error => console.error('Fetch 에러:', error));
- 특정 ID의 단일 리소스 조회

리소스 경로 뒤에 /{id}를 붙여 특정 ID를 가진 단 하나의 데이터만 정확히 가져올 수 있습니다. 예를 들어 ID가 10인 게시물을 조회해 봅시다.


# curl을 이용한 요청
curl https://jsonplaceholder.typicode.com/posts/10

fetch('https://jsonplaceholder.typicode.com/posts/10')
  .then(response => response.json())
  .then(post => console.log(post));
// {
//   "userId": 1,
//   "id": 10,
//   "title": "optio molestias id quia eum",
//   "body": "quo et expedita modi cum officia vel magni\ndoloribus qui repudiandae\nvero nisi sit\nquos veniam quod sed accusamus veritatis error"
// }
- 중첩된 리소스 조회 (Nested Resources)

JSONPlaceholder의 큰 장점 중 하나는 리소스 간의 관계를 활용한 조회가 가능하다는 것입니다. 예를 들어, ID가 1인 게시물(post)에 달린 모든 댓글(comments)을 조회하고 싶다면 다음과 같이 요청할 수 있습니다.


# curl을 이용한 요청
curl https://jsonplaceholder.typicode.com/posts/1/comments

fetch('https://jsonplaceholder.typicode.com/posts/1/comments')
  .then(response => response.json())
  .then(comments => {
    console.log('게시물 1의 댓글 목록:', comments);
    // [
    //   { "postId": 1, "id": 1, ... },
    //   { "postId": 1, "id": 2, ... },
    //   ...
    // ]
  });

반대로 특정 사용자가 작성한 모든 게시물을 조회할 수도 있습니다. ID가 2인 사용자가 작성한 모든 할 일 목록(todos)을 가져와 봅시다.


# curl을 이용한 요청
curl "https://jsonplaceholder.typicode.com/users/2/todos"
- 쿼리 파라미터를 이용한 필터링

URL의 ? 뒤에 key=value 형식의 쿼리 파라미터를 추가하여 원하는 조건에 맞는 데이터만 필터링할 수 있습니다. 예를 들어, 모든 댓글 중에서 postId가 1인 댓글들만 필터링해서 가져오고 싶다면 다음과 같습니다. (위의 중첩 리소스 조회와 동일한 결과를 반환합니다.)


# curl을 이용한 요청
curl "https://jsonplaceholder.typicode.com/comments?postId=1"

// postId가 1인 댓글과 2인 댓글을 동시에 조회
const params = new URLSearchParams({
  postId: [1, 2]
});

fetch(`https://jsonplaceholder.typicode.com/comments?${params.toString()}`)
  .then(response => response.json())
  .then(comments => console.log('postId가 1 또는 2인 댓글들:', comments));

이 필터링 기능은 /posts 리소스에 userId를 적용하는 등 다양한 조합으로 활용될 수 있어 매우 유용합니다.

B. POST: 새로운 데이터 생성하기 (Create)

POST 메서드는 서버에 새로운 리소스를 생성할 때 사용됩니다. 요청 본문(Request Body)에 생성할 데이터의 정보를 담아 전송하면, 서버는 이 데이터를 받아 새로운 리소스를 생성하고, 생성된 리소스의 정보(주로 새로운 ID가 할당된)를 응답으로 돌려줍니다.

중요: JSONPlaceholder는 '가짜' API이므로 실제로 데이터가 서버에 영구적으로 저장되지는 않습니다. 요청을 보낼 때마다 성공적으로 생성되었다는 응답(주로 ID 101 또는 501 등 기존 데이터의 다음 번호)을 시뮬레이션하여 반환할 뿐입니다.

새로운 게시물을 생성하는 예제를 살펴봅시다.


const newPost = {
  title: '새로운 게시물 제목',
  body: '이것은 테스트용으로 생성된 게시물 내용입니다.',
  userId: 1
};

fetch('https://jsonplaceholder.typicode.com/posts', {
  method: 'POST',
  body: JSON.stringify(newPost), // JavaScript 객체를 JSON 문자열로 변환
  headers: {
    'Content-type': 'application/json; charset=UTF-8', // 보내는 데이터의 타입을 명시
  },
})
.then(response => response.json())
.then(json => console.log('서버로부터 받은 응답:', json));
// 서버로부터 받은 응답:
// {
//   "title": "새로운 게시물 제목",
//   "body": "이것은 테스트용으로 생성된 게시물 내용입니다.",
//   "userId": 1,
//   "id": 101 // 서버에서 새로 할당해 준 ID
// }

curl을 사용하면 다음과 같습니다.


curl -X POST -H "Content-Type: application/json" \
-d '{"title": "새로운 게시물 제목", "body": "이것은 테스트용 내용입니다.", "userId": 1}' \
https://jsonplaceholder.typicode.com/posts

C. PUT: 데이터 전체 수정하기 (Update)

PUT 메서드는 특정 리소스의 전체 데이터를 교체(replace)하는 방식으로 수정할 때 사용됩니다. 즉, 요청 본문에 보낸 데이터가 기존 데이터를 완전히 덮어쓰게 됩니다. 따라서 PUT 요청을 보낼 때는 해당 리소스의 모든 필드를 포함하여 보내는 것이 일반적입니다.

ID가 1인 게시물의 내용을 완전히 수정해 보겠습니다.


const updatedPost = {
  id: 1, // 수정할 리소스의 ID를 명시
  title: '수정된 타이틀입니다',
  body: '내용도 완전히 새로 작성되었습니다.',
  userId: 1
};

fetch('https://jsonplaceholder.typicode.com/posts/1', {
  method: 'PUT',
  body: JSON.stringify(updatedPost),
  headers: {
    'Content-type': 'application/json; charset=UTF-8',
  },
})
.then(response => response.json())
.then(json => console.log('수정 후 받은 응답:', json));
// 수정 후 받은 응답:
// {
//   "id": 1,
//   "title": "수정된 타이틀입니다",
//   "body": "내용도 완전히 새로 작성되었습니다.",
//   "userId": 1
// }

D. PATCH: 데이터 부분 수정하기 (Update)

PATCH 메서드는 PUT과 마찬가지로 데이터를 수정하지만, 리소스의 일부 필드만을 수정한다는 점에서 차이가 있습니다. 전체 데이터를 보내지 않고, 변경하려는 필드만 요청 본문에 담아 보내면 됩니다. 이는 네트워크 효율성 면에서 PUT보다 유리합니다.

ID가 1인 게시물의 title만 수정해 보겠습니다.


fetch('https://jsonplaceholder.typicode.com/posts/1', {
  method: 'PATCH',
  body: JSON.stringify({
    title: '타이틀만 부분적으로 수정했어요!', // body나 userId는 보내지 않음
  }),
  headers: {
    'Content-type': 'application/json; charset=UTF-8',
  },
})
.then(response => response.json())
.then(json => console.log('부분 수정 후 받은 응답:', json));
// 부분 수정 후 받은 응답:
// {
//   "userId": 1,
//   "id": 1,
//   "title": "타이틀만 부분적으로 수정했어요!", // title만 변경됨
//   "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto" // 기존 body는 그대로 유지됨
// }

E. DELETE: 데이터 삭제하기 (Delete)

DELETE 메서드는 이름 그대로 특정 리소스를 삭제할 때 사용됩니다. 삭제하려는 리소스의 엔드포인트(/resource/{id})로 DELETE 요청을 보내면 됩니다. 성공적으로 삭제되면 서버는 보통 200 OK 상태 코드와 함께 비어있는 응답 본문을 반환합니다.

ID가 1인 게시물을 삭제하는 시뮬레이션입니다.


fetch('https://jsonplaceholder.typicode.com/posts/1', {
  method: 'DELETE',
})
.then(response => {
  console.log('응답 상태 코드:', response.status); // 200
  return response.json(); // 본문은 비어있음
})
.then(json => console.log('응답 본문:', json)); // 응답 본문: {}

마찬가지로, 이 삭제 작업은 영구적이지 않으며, 다시 해당 리소스로 GET 요청을 보내면 데이터가 그대로 존재하는 것을 확인할 수 있습니다. 중요한 것은 DELETE 요청을 보내고 성공적인 응답(200 상태 코드)을 받는 '과정'을 테스트할 수 있다는 점입니다.

JSONPlaceholder를 넘어, 더 강력한 Mock API 서비스들

JSONPlaceholder는 기본을 다지기에 훌륭하지만, 실제 개발 환경은 더 복잡한 요구사항을 가집니다. 직접 데이터 구조를 정의하거나, 에러 상황을 시뮬레이션하거나, 응답 지연을 테스트해야 할 때가 있습니다. 이럴 때 사용할 수 있는 다른 유용한 Mock API 서비스들을 소개합니다.

1. Reqres (Request-Response)

웹사이트: https://reqres.in/

Reqres는 '실제와 같은 응답(Real-like responses)'을 모토로 합니다. 사용자 관리(목록 조회, 생성, 수정)와 로그인(성공/실패) 시나리오 테스트에 특화되어 있습니다. 특히 응답 지연(Delayed Response) 기능을 제공하여, 네트워크가 느린 환경을 시뮬레이션하고 로딩 인디케이터나 스켈레톤 UI가 올바르게 동작하는지 테스트하는 데 매우 유용합니다.


# 3초 지연된 사용자 목록 응답을 요청
curl "https://reqres.in/api/users?delay=3"

2. MockAPI

웹사이트: https://mockapi.io/

MockAPI는 JSONPlaceholder나 Reqres보다 한 단계 더 나아가, 사용자가 직접 데이터 스키마(구조)를 정의하고 자신만의 Mock API 엔드포인트를 생성할 수 있게 해줍니다. GUI 기반의 직관적인 인터페이스를 통해 프로젝트에 필요한 데이터 모델(예: 'product', 'cart_item' 등)을 만들고, 각 필드의 타입(문자열, 숫자, 날짜 등)을 지정할 수 있습니다. Faker.js 라이브러리가 내장되어 있어 사실적인 가짜 데이터를 자동으로 채워주는 기능도 매우 강력합니다.

3. Beeceptor

웹사이트: https://beeceptor.com/

Beeceptor는 단순한 Mock API 서버를 넘어 API 요청/응답을 가로채고(intercept) 검사하는 강력한 디버깅 도구의 역할까지 수행합니다. 특정 엔드포인트를 생성해두면, 그곳으로 들어오는 모든 HTTP 요청을 실시간으로 확인하고, 사전에 정의한 규칙에 따라 동적으로 응답을 조작할 수 있습니다. 예를 들어, '요청 헤더에 특정 값이 포함되어 있으면 401 Unauthorized 에러를 반환하라'와 같은 복잡한 시나리오를 손쉽게 구현할 수 있어, 예외 처리 로직을 테스트하는 데 최적입니다.

4. Mocky.io

웹사이트: https://www.mocky.io/

Mocky는 가장 빠르고 간단하게 일회성 Mock 응답을 생성하는 데 특화된 서비스입니다. 웹사이트에서 원하는 HTTP 상태 코드, 응답 헤더, 응답 본문(JSON, XML, text 등)을 직접 입력하고 'Generate my HTTP Response' 버튼만 누르면 즉시 사용할 수 있는 고유한 URL이 생성됩니다. 복잡한 리소스 관리 없이 특정 에러 상황(예: 500 Internal Server Error, 403 Forbidden)에 대한 클라이언트의 동작을 빠르게 테스트하고 싶을 때 매우 유용합니다.

결론: Mock API로 스마트하게 개발 워크플로우 개선하기

프론트엔드 개발에서 백엔드를 기다리는 시대는 지났습니다. 이제 Mock API는 선택이 아닌 필수 도구로 자리 잡았습니다. 오늘 살펴본 JSONPlaceholder와 같은 서비스들을 활용하면, 우리는 더 이상 외부 요인에 의해 개발이 중단되는 일 없이 주도적으로 프로젝트를 이끌어 나갈 수 있습니다.

Mock API를 통해 데이터 로딩, 성공, 실패, 로딩 중 등 다양한 상태에 대한 UI를 완벽하게 구현하고, 복잡한 비동기 로직을 사전에 철저히 검증함으로써 코드의 안정성과 완성도를 크게 높일 수 있습니다. 이는 결국 더 빠른 개발 속도, 더 높은 품질의 제품, 그리고 개발자 자신의 스트레스 감소로 이어질 것입니다.

아직 Mock API 사용을 망설이고 있다면, 지금 바로 브라우저를 열고 JSONPlaceholder에 첫 번째 fetch 요청을 보내보세요. 여러분의 개발 경험이 한 차원 더 높아지는 것을 느끼실 수 있을 겁니다.