본문 바로가기
바이브코딩

#2 PHP를 통한 REST API 구현 예제

by ethanjoh 2026. 7. 6.

2026.07.06 - [바이브코딩] - #1 REST API란?

 

 

앞서 REST API가 무엇인지 알아보았는데 실제로 PHP를 통해 어떻게 구현하는지 간단한 사례를 보겠습니다.

server.php와 client.php 2개의 파일을 미리 만들고 구글 안티그래비티에서 실행하도록 시켜봤습니다.

 

작업을 시키면 안티그래비티에서 로컬 서버를 띄우고, 브라우저 상에서 테스트를 하고 스크린샷까지 찍어서 보고서를 만들어줍니다.

 


<server.php>

구동방법은 터미널을 열고 php -S localhost:8000 server.php 를 입력합니다.

<?php
// 상품 정보를 관리하는 간단한 PHP REST API 서버 모듈

/**
 * 간단한 PHP REST API 서버 예제 (server.php)
 * 
 * [구동 방법]
 * 터미널에서 이 파일이 있는 디렉터리로 이동한 후, PHP 내장 웹 서버를 실행합니다:
 * $ php -S localhost:8000 server.php
 */

// 1. 응답 데이터의 포맷을 JSON 형식(UTF-8 인코딩)으로 지정합니다.
// 클라이언트는 이 헤더를 통해 응답 본문이 JSON 형태임을 인식합니다.
header("Content-Type: application/json; charset=UTF-8");

// 2. 파일 기반 가상 데이터베이스(JSON 파일) 경로를 설정합니다.
$db_file = __DIR__ . '/database.json';

// 3. database.json 파일이 존재하지 않는 경우 기본 초기 데이터를 생성합니다.
if (!file_exists($db_file)) {
    $initial_data = [
        ["id" => 1, "name" => "아메리카노", "price" => 3000],
        ["id" => 2, "name" => "카페라떼", "price" => 3500]
    ];
    // JSON 형태로 변환하여 파일에 저장 (한글 깨짐 방지 및 보기 쉬운 JSON 인덴트 적용)
    file_put_contents($db_file, json_encode($initial_data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
}

// 4. 클라이언트의 HTTP 요청 정보(메서드 및 요청 URL)를 추출합니다.
$method = $_SERVER['REQUEST_METHOD']; // GET, POST 등 요청 방식
$request_uri = $_SERVER['REQUEST_URI']; // 요청받은 전체 URI 경로
$path = parse_url($request_uri, PHP_URL_PATH); // Query String을 제외한 순수 경로 파싱

// 5. 라우팅 처리: 현재 서버는 /products 엔드포인트만 지원합니다.
if ($path !== '/products') {
    http_response_code(404); // 404 Not Found 상태 코드 설정
    echo json_encode(["error" => "요청하신 경로를 찾을 수 없습니다."], JSON_UNESCAPED_UNICODE);
    exit; // 실행 종료
}

// 6. 데이터베이스 파일에서 현재 저장된 전체 상품 데이터를 읽어옵니다.
$products = json_decode(file_get_contents($db_file), true);

// 7. HTTP 메서드(GET, POST 등)에 따른 CRUD 분기 처리
switch ($method) {
    case 'GET':
        // ==========================================
        // 1) 전체 상품 목록 조회 (Read)
        // ==========================================
        http_response_code(200); // 200 OK 상태 코드 설정
        // 전체 상품 데이터를 JSON 문자열로 변환하여 출력
        echo json_encode($products, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
        break;

    case 'POST':
        // ==========================================
        // 2) 신규 상품 추가 (Create)
        // ==========================================
        // 클라이언트가 보내온 HTTP Request Body(JSON 데이터)를 읽고 배열로 변환합니다.
        $input_data = json_decode(file_get_contents('php://input'), true);

        // 필수 입력 필드(name: 상품명, price: 가격) 유효성 검사
        if (!isset($input_data['name']) || !isset($input_data['price'])) {
            http_response_code(400); // 400 Bad Request 상태 코드 설정
            echo json_encode(["error" => "상품 이름(name)과 가격(price)은 필수 입력 사항입니다."], JSON_UNESCAPED_UNICODE);
            exit;
        }

        // 새로운 상품 ID 자동 발급 (기존 ID 중 최댓값 + 1)
        $new_id = empty($products) ? 1 : max(array_column($products, 'id')) + 1;
        $new_product = [
            "id" => $new_id,
            "name" => $input_data['name'],
            "price" => (int)$input_data['price']
        ];

        // 상품 배열에 새 상품 추가 후 JSON 파일에 업데이트 저장
        $products[] = $new_product;
        file_put_contents($db_file, json_encode($products, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));

        http_response_code(201); // 201 Created 상태 코드 설정
        echo json_encode([
            "message" => "새로운 상품이 성공적으로 추가되었습니다.",
            "product" => $new_product
        ], JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
        break;

    default:
        // ==========================================
        // 3) 지원하지 않는 HTTP 메서드 예외 처리
        // ==========================================
        http_response_code(405); // 405 Method Not Allowed 상태 코드 설정
        echo json_encode(["error" => "지원하지 않는 요청 방식입니다."], JSON_UNESCAPED_UNICODE);
        break;
}

 

 

<client.php>

구동방법은 터미널을 하나 더 실행해서 php client.php를 입력하면 됩니다.

<?php
// cURL 모듈을 사용하여 REST API와 통신하는 PHP 클라이언트 예제

/**
 * 간단한 PHP REST API 클라이언트 예제 (client.php)
 * 
 * [구동 방법]
 * 먼저 다른 터미널에서 server.php를 실행해 둔 상태여야 합니다.
 * $ php client.php
 */

// 테스트 대상 REST API 서버 엔드포인트 URL
$api_url = "http://localhost:8000/products";

// 웹 브라우저에서 접속했을 때 줄바꿈이 깔끔하게 표시되도록 <pre> 태그 추가
echo "<pre>\n";

// ==============================================================================
// 1. 현재 상품 목록 조회 (GET 요청)
// ==============================================================================
echo "=== 1. 현재 상품 목록 조회 (GET 요청) ===\n";

// cURL 세션 초기화
$ch = curl_init($api_url);

// cURL 옵션 설정: curl_exec() 실행 시 응답 결과를 직접 출력하지 않고 문자열로 반환받습니다.
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

// cURL 요청 실행 및 응답 수신
$response = curl_exec($ch);

// HTTP 상태 코드(200, 201, 404 등) 가져오기
$status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);

// 예외 처리: API 서버에 접속할 수 없는 경우 (서버 미실행 등)
if ($response === false) {
    echo "서버 연결 실패! 먼저 다른 터미널에서 php -S localhost:8000 server.php 를 실행했는지 확인해주세요.\n";
    curl_close($ch);
    echo "</pre>\n";
    exit;
}

echo "HTTP 상태 코드: $status_code\n";
echo "응답 데이터:\n$response\n\n";

// 사용이 완료된 cURL 리소스를 해제합니다.
curl_close($ch);


// ==============================================================================
// 2. 신규 상품 등록 (POST 요청)
// ==============================================================================
echo "=== 2. 신규 상품 등록 (POST 요청) ===\n";

// 서버에 등록할 새로운 상품 데이터 배열 생성
$new_product_data = [
    "name" => "바닐라라떼",
    "price" => 4000
];

// PHP 배열을 REST API에 전송하기 위해 JSON 문자열 포맷으로 변환(인코딩)합니다.
$json_payload = json_encode($new_product_data);

// cURL 세션 초기화
$ch = curl_init($api_url);

// cURL 옵션 설정
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 응답 결과를 반환값으로 수신
curl_setopt($ch, CURLOPT_POST, true);           // HTTP 메서드를 POST 방식으로 지정
curl_setopt($ch, CURLOPT_POSTFIELDS, $json_payload); // Request Body에 보낼 JSON 데이터 전달

// HTTP 헤더 설정: 데이터 타입이 JSON 임을 명시
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'Content-Length: ' . strlen($json_payload)
]);

// POST 요청 실행
$response = curl_exec($ch);
$status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);

echo "HTTP 상태 코드: $status_code\n";
echo "응답 데이터:\n$response\n\n";

// cURL 리소스 해제
curl_close($ch);


// ==============================================================================
// 3. 등록 후 전체 상품 목록 재조회 (GET 요청)
// ==============================================================================
echo "=== 3. 등록 후 전체 상품 목록 재조회 (GET 요청) ===\n";

// cURL 세션 초기화
$ch = curl_init($api_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

// GET 요청 실행
$response = curl_exec($ch);
$status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);

echo "HTTP 상태 코드: $status_code\n";
echo "응답 데이터:\n$response\n";

// cURL 리소스 해제
curl_close($ch);

// <pre> 태그 닫기
echo "</pre>\n";

 


REST API 웹 브라우저 테스트 완료 보고서

1. 테스트 개요

  • API 서버 (server.php): http://localhost:8000/products
  • 테스트 클라이언트 (client.php): http://localhost:8001/

2. 웹 브라우저 테스트 결과

1) 클라이언트 실행 테스트 (http://localhost:8001/)

브라우저에서 client.php 페이지 접속 시 API와의 통신 결과가 정상 출력되었습니다:

  • === 1. 현재 상품 목록 조회 (GET 요청) ===
    • HTTP 상태 코드: 200
    • 응답 데이터:
      [
          {"id": 1, "name": "아메리카노", "price": 3000},
          {"id": 2, "name": "카페라떼", "price": 3500}
      ]
      
  • === 2. 신규 상품 등록 (POST 요청) ===
    • HTTP 상태 코드: 201
    • 등록 데이터: {"name": "바닐라라떼", "price": 4000}
    • 응답 데이터:
      {
          "message": "새로운 상품이 성공적으로 추가되었습니다.",
          "product": {"id": 3, "name": "바닐라라떼", "price": 4000}
      }
      
  • === 3. 등록 후 전체 상품 목록 재조회 (GET 요청) ===
    • HTTP 상태 코드: 200
    • 응답 데이터: 총 3개(아메리카노, 카페라떼, 바닐라라떼) 상품 등록 확인.

2) REST API 엔드포인트 직접 접속 테스트 (http://localhost:8000/products)

API 서버 엔드포인트에 직접 접속 시 저장된 database.json 데이터가 JSON 형태로 정상 제공됩니다.

[
    { "id": 1, "name": "아메리카노", "price": 3000 },
    { "id": 2, "name": "카페라떼", "price": 3500 },
    { "id": 3, "name": "바닐라라떼", "price": 4000 }
]

3. 브라우저 테스트 시각 자료

 


 

PHP REST API 작동 방식 안내서

이 프로젝트는 PHP를 이용한 간단한 **RESTful API 서버(server.php)**와 이를 cURL로 테스트하는 **클라이언트(client.php)**로 구성되어 있습니다.


1. 전체 시스템 구조 및 흐름

client.php가 **cURL (HTTP 클라이언트 모듈)**을 사용해 HTTP 요청을 보내면, server.php가 요청을 받아 **JSON 데이터베이스 파일(database.json)**을 조작한 후 결과를 HTTP 응답으로 돌려줍니다.

 


2. 모듈별 세부 동작 방식

🛠️ 서버 모듈 (server.php)

  1. HTTP 응답 헤더 설정:
    • Content-Type: application/json; charset=UTF-8 헤더를 통해 응답이 JSON 포맷임을 명시합니다.
  2. 파일 데이터베이스 (database.json) 관리:
    • 서버 실행 시 database.json 파일의 존재 여부를 확인하고, 없으면 기본 초기 데이터(아메리카노, 카페라떼)를 자동 생성합니다.
  3. 라우팅 및 URL 검증:
    • $_SERVER['REQUEST_METHOD']로 HTTP 요청 방식(GET, POST 등)을 감지합니다.
    • parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH)로 경로를 확인하며, /products가 아닌 요청은 HTTP 404 Not Found로 차단합니다.
  4. HTTP 메서드별 처리:
    • GET /products: database.json 파일의 상품 배열 전체를 읽어 HTTP 200 OK와 함께 JSON 형식으로 출력합니다.
    • POST /products:
      • php://input 스트림에서 요청 본문(JSON)을 읽습니다.
      • 필수 항목(name, price) 유효성 검증 실패 시 HTTP 400 Bad Request를 응답합니다.
      • 기존 ID 중 최댓값 + 1로 새 ID를 생성하고 database.json에 업데이트 후 HTTP 201 Created를 응답합니다.
    • 기타 메서드: 지원하지 않는 HTTP 요청 시 HTTP 405 Method Not Allowed를 반환합니다.

📱 클라이언트 모듈 (client.php)

  1. GET 요청 (초기 상품 목록 조회):
    • curl_init("http://localhost:8000/products") 세션 생성 후 GET 요청을 전달하여 결과를 수신합니다.
  2. POST 요청 (신규 상품 "바닐라라떼" 등록):
    • PHP 배열 데이터를 json_encode()로 변환 후 CURLOPT_POSTFIELDS에 담아 보냅니다.
    • Content-Type: application/json 헤더를 지정하여 전송합니다.
  3. GET 요청 (목록 재조회):
    • 등록 결과를 확인하기 위해 다시 한번 GET 요청을 실행하고 3개의 상품 데이터를 수신합니다.

3. 구동 및 테스트 방법

1) PHP 내장 서버 구동

터미널에서 아래 명령어로 서버 및 클라이언트를 구동합니다:

# REST API 서버 실행 (8000번 포트)
php -S localhost:8000 server.php

# (선택) 클라이언트 웹 페이지 실행 (8001번 포트, curl 확장 로드 필요 시 -d extension=curl 추가)
php -d extension=curl -S localhost:8001 client.php

2) 테스트 접속 URL

  • API 서버 엔드포인트: http://localhost:8000/products
  • 클라이언트 테스트 페이지: http://localhost:8001/

 

 

 

'바이브코딩' 카테고리의 다른 글

#1 REST API란?  (0) 2026.07.06
Firebase vs Supabase  (0) 2026.07.06
SQL vs NoSQL 데이터베이스 선택  (0) 2026.07.06
배포와 CI/CD 완벽가이드  (0) 2026.07.06
도커의 모든 것: 완벽한 밀키트  (0) 2026.07.05