PHPで作ったREST APIを生成AIと連携する方法:【前編】最低限の構成でREST APIを動かす手順解説

近年、ChatGPTをはじめとする生成AIとの連携がWebサービス開発において重要な要素となっています。生成AIが外部APIを利用して動的な情報を取得・操作できるようになることで、その活用範囲は大きく広がっています。この記事では、SlimやLaravelといったフレームワークを使わずに、PHPのみでシンプルなREST APIを構築する方法を解説します。次回の後編では、このAPIをChatGPTなどと連携させるためのOpenAPI仕様の書き方も解説しますので、まずは「動くAPI」を一緒に作っていきましょう。

RREST APIとは?そしてなぜ必要なのか

まずは基礎知識として「REST APIとは何か」を理解しましょう。

REST(Representational State Transfer)APIとは、HTTPプロトコル上で「リソース(データ)」をやり取りするための仕組みであり、URI(URL)は処理ではなくリソースを表すことが原則です。

つまり、URLは「何をするか」ではなく「何に対して操作するか」を示し、操作の種類(取得、追加、更新、削除)はHTTPメソッド(GET, POST, PUT, DELETE)によって決定されます。

例えば以下のような形式です:

メソッド意味
GETデータの取得/api/products?id=101
POST新規データ追加/api/products(POST)
PUTデータの更新/api/products?id=101
DELETEデータの削除/api/products?id=101

このように、URLの役割とメソッドの役割を明確に分離することで、シンプルで一貫性のあるAPI設計が可能になります。

REST APIは生成AIと特に相性が良い

REST APIは以下の点において、生成AIとの連携に特に適しています:

  • HTTPベースであるため、生成AI側が容易にリクエストできる
  • JSON形式でやり取りすることで、構造化データとして理解しやすい
  • OpenAPI仕様に対応させることで、GPTsなどが自動でAPI仕様を解釈できる
  • ステートレス性により、リクエスト単位で完結し、疎結合な設計ができる

このように、REST APIは生成AIにとって外部情報を取得・操作するための標準的かつ柔軟な手段として非常に適しており、ChatGPTのようなAIにとっては「外部の知識ベース」として活用するのに理想的な形式です。


今回作るREST APIの仕様と目的

今回は以下のような仕様のAPIを作成します。

  • エンドポイント:/api/products
  • 機能:商品一覧の取得、またはID指定による商品詳細取得
  • データ:ファイル(JSON)ベースで管理

目的は「小規模でも今すぐ動くREST API」を作ることで、生成AIと接続できる足場をつくることです。


ディレクトリ構成を用意する

API用のディレクトリ構成は以下のようにします。

project/
├── api/
│   ├── index.php
│   ├── routes/
│   │   └── products.php
│   └── data/
│       └── products.json
└── .htaccess

なぜこの構成?

  • index.php: 全リクエストをここで受け取るフロントコントローラ
  • routes/: リクエストごとの処理を分離
  • data/: データストレージ(今回は簡易的にJSONファイル)
  • .htaccess: ルーティング制御(Apache環境を想定)

.htaccess の設定(Apacheでのルーティング)

Apacheでは、静的ファイル以外のリクエストをすべて index.php に転送する必要があります。

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ api/index.php [QSA,L]

解説

  • !-f で物理ファイルが存在しないリクエストのみを対象に
  • /api/index.php に転送し、そこでルーティングを行う

index.php の実装:ルーティング処理

api/index.php では、リクエストURIに応じて処理を振り分けます。

<?php
// CORS対応ヘッダー
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type");

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(200);
    exit;
}

$requestUri = $_SERVER['REQUEST_URI'];
$requestMethod = $_SERVER['REQUEST_METHOD'];

if (preg_match('#/api/products#', $requestUri)) {
    require_once __DIR__ . '/routes/products.php';
    handleProducts($requestMethod);
    exit;
}

http_response_code(404);
echo json_encode(['error' => 'Not Found']);

routes/products.php:APIロジックの記述

<?php
function handleProducts($method) {
    header('Content-Type: application/json');

    $dataFile = __DIR__ . '/../data/products.json';
    $products = json_decode(file_get_contents($dataFile), true);

    if ($products === null) {
        http_response_code(500);
        echo json_encode(['error' => 'データの読み込みに失敗しました']);
        return;
    }

    if ($method === 'GET') {
        if (isset($_GET['id'])) {
            $id = $_GET['id'];
            $product = array_filter($products, fn($p) => $p['id'] == $id);
            echo json_encode(array_values($product));
        } else {
            echo json_encode($products);
        }
    } else {
        http_response_code(405);
        echo json_encode(['error' => 'Method Not Allowed']);
    }
}

解説

  • GETリクエストを受け、id パラメータがある場合は個別商品を返す
  • なければ全商品一覧を返す
  • ファイルから読み込むことで、DB不要で試せる

補足

今回は簡易的な例として、GETメソッドのみで JSON ファイルからデータを読み取り、出力する構成としていますが、実運用では以下のような拡張が可能です:

  • POST:新規商品の追加
  • PUT:既存商品の更新
  • DELETE:商品の削除
  • MySQLやPostgreSQLなどのデータベースと接続して、より動的なデータ取得・保存を行う

これらを実装することで、より高度で実用的なREST APIに発展させることができます。


products.json:ダミーデータの準備

[
  { "id": 101, "name": "ハンドドリル", "price": 1980 },
  { "id": 102, "name": "インパクトドライバー", "price": 2980 },
  { "id": 103, "name": "丸ノコ", "price": 4980 },
  { "id": 104, "name": "工具セット(30点)", "price": 7980 },
  { "id": 105, "name": "電動サンダー", "price": 3980 }
]

解説

このファイルは簡易的なデータベースとして使用します。生成AIと接続する際にも、このような構造化されたレスポンスを返すことで理解・利用されやすくなります。


CORS(クロスオリジン)対応を追加する

生成AIや外部フロントエンドアプリケーションからAPIを呼び出す場合、CORS(Cross-Origin Resource Sharing)の設定が必要になることがあります。

なぜCORSが必要?

JavaScriptからAPIを呼び出すとき、異なるオリジン(例:別ドメインやポート)間の通信には制限がかかります。これを許可するためには、API側で明示的にヘッダーを返す必要があります。

対応方法:index.php にヘッダーを追加

※ CORS対応ヘッダーはindex.phpの冒頭に記述してください。レスポンスを出力する前にヘッダーが送られる必要があります。

// CORS対応ヘッダー(index.phpの先頭付近に記述)
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type");

// プリフライトリクエストへの対応(OPTIONSメソッド)
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(200);
    exit;
}

解説

  • Access-Control-Allow-Origin: *:すべてのオリジンからのアクセスを許可(必要に応じて制限可能)
  • OPTIONS メソッドは「本リクエストの前に送られる確認リクエスト」なので、それ単体でも成功レスポンスを返す必要があります

この設定により、生成AIや外部アプリケーションからでも安全かつスムーズにAPIを利用可能になります。


動作確認:ローカルサーバーを起動する

PHPのビルトインサーバーでローカル実行が可能です。

php -S localhost:8000

リクエスト確認(curlやブラウザ)

curl http://localhost:8000/api/products
curl http://localhost:8000/api/products?id=101

補足:運用時の注意点

この構成はあくまで検証・学習用途を前提としています。実際のサービスに導入する場合は、以下のようなセキュリティ・運用対策が重要です:

  • 入力値のバリデーション(SQLインジェクションやXSSの防止)
  • 認証・認可(APIトークンやJWTなど)
  • ログの記録と監視(エラーやアクセス状況の把握)
  • HTTPSの利用(通信の暗号化)
  • エラーハンドリングの統一とログ化

まとめ:REST APIはPHPだけでも作れる

本記事では、SlimやLaravelといったフレームワークを使わず、PHPのみでREST APIを構築する方法を解説しました。生成AIと連携するためには、このように「決まったURLにアクセスすれば、JSON形式で構造化されたレスポンスが返ってくる」APIが必要です。

後編では、このAPIをChatGPTなどの生成AIと連携する方法を解説します。OpenAPI仕様の書き方や、GPTsからの接続手順などを実践的に学びましょう。

後編はこちら

Contact

ウェブサイトの制作や運用に関わる
お悩みやご相談
お気軽にお問い合わせ下さい

ウェブサイトと一口に言っても、企業サイトやECサイト、ブログ、SNSなど、その“カタチ”は目的に応じてさまざまであり、構築方法や使用する技術も大きく異なります。株式会社コナックスでは、お客様のご要望やブランドの個性を丁寧に汲み取り、最適なウェブサイトの“カタチ”をご提案いたします。

デザイン、ユーザビリティ、SEO対策はもちろん、コンテンツ制作やマーケティング戦略に至るまで、あらゆるフェーズでお客様のビジネスに寄り添い、成果につながるウェブサイトづくりをサポートいたします。私たちは、ウェブサイトの公開をゴールではなくスタートと捉え、お客様のビジネスの成功に向けて共に伴走してまいります。