簡単なRESTful APIサーバーを作ってみる

RESTful APIって?

標準的なWebAPIの設計方式。
リソースに対するURLを1つだけ用意し、HTTPメソッドの切り替えで操作を表す。

  • 読書リストのうち、ID「0001」の本を取得する

    • (URL)https://xxxxx/readinglist/0001
    • (HTTPメソッド) GET
  • 読書リストのうち、ID「1000」の本を削除する

    • (URL)https://xxxxx/readinglist/1000
    • (HTTPメソッド) DELETE

RESTful APIはステートレスであるべき

ステートレス = WebAPIサーバはセッション変数を持つべきではない。
サーバ間で共有ができなくなる。などの問題があるから。
スケーラビリティの問題。(今後サーバを増やしたいときとか)

PHPでRESTfulAPIサーバ、クライアントの作成

環境

macOS BigSur 11.0.1

PHP 7.3.22

MAMP 5.7

サーバサイドのPHPファイルを作成


declare(strict_types=1);

// GET
function getMessage()
{
  $res = [
    'status' => 'success',
    'message' => 'ユーザ: ' . $_GET['userName'] . 'の好きな食べ物は、' . $_GET['food'] . 'です。',
  ];
  return $res;
}

//POST
function postMessage()
{
  $res = [
    'status' => 'success',
    'message' => 'ユーザ: ' . $_POST['userName'] . 'の好きな食べ物を、' . $_POST['food'] . 'に登録しました。',
  ];
  return $res;
}

// PUT
function putMessage()
{
  parse_str(file_get_contents('php://input'), $putRequest);
  $res = [
      'status' => 'success',
      'message' => 'ユーザ: ' . $putRequest['userName'] . 'の好きな食べ物を、 ' . $putRequest['food'] . 'に変更しました。',
  ];
  return $res;
}

// DELETE
function deleteMessage()
{
  parse_str(file_get_contents('php://input'), $deleteRequest);
  $res = [
      'status' => 'success',
      'message' => 'ユーザ: ' . $deleteRequest['userName'] . 'の好きな食べ物、' . $deleteRequest['food'] . 'を削除しました。',
  ];
  return $res;
}

switch (strtolower($_SERVER['REQUEST_METHOD'])) {
  case 'get':
    echo json_encode(getMessage());
    break;
  case 'post':
    echo json_encode(postMessage());
    break;
  case 'put':
    echo json_encode(putMessage());
    break;
  case 'delete':
    echo json_encode(deleteMessage());
    break;
}

クライアントサイドのPHPファイルを作成

cUEL関数を使用。

  • curl_init() でURLを指定。cURLハンドルを取得。
  • curl_setopt() でオプションの指定。
  • curl_exec() でハンドルを渡し、リクエストを送信。レスポンスを取得。
  • curl_close() でハンドルを閉じる。

GET


declare(strict_types=1);

$params = [
    'userId' => 1001,
    'userName' => "kona",
    'food' => '抹茶',
];

$url = "http://localhost:8888/server.php?" . http_build_query($params);

$handle = curl_init($url);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
$apiResponse = json_decode(curl_exec($handle), true);
curl_close($handle);

echo "サーバからの応答:\n";
print_r($apiResponse);

実行結果


サーバからの応答:
Array
(
    [status] => success
    [message] => ユーザ: konaの好きな食べ物は、抹茶です。
)

http_build_query()で連想配列をパラメータ文字列へ。


$params = [
        'userId' => 1001,
        'userName' => "kona",
        'food' => '抹茶',
    ];


userId=1001&userName=kona&food=抹茶(Unicodeに変換される)

POST


declare(strict_types=1);

$params = [
    'userId' => 1001,
    'userName' => "kona",
    'food' => '抹茶',
];

$opt = [
    CURLOPT_URL => 'http://localhost:8888/server.php',
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS => $params,
    CURLOPT_RETURNTRANSFER => true,
];

$handle = curl_init();
curl_setopt_array($handle, $opt);
$apiResponse = json_decode(curl_exec($handle), true);
curl_close($handle);

echo "サーバからの応答:\n";
print_r($apiResponse);

実行結果


サーバからの応答:
Array
(
    [status] => success
    [message] => ユーザ: konaの好きな食べ物を、抹茶に登録しました。
)

curl_setopt_array()で配列で指定した設定を適応できる。

PUT


declare(strict_types=1);

$params = [
    'userId' => 1001,
    'userName' => "kona",
    'food' => '抹茶アイス',
];

$opt = [
    CURLOPT_URL => 'http://localhost:8888/server.php',
    CURLOPT_CUSTOMREQUEST => 'PUT',
    CURLOPT_POSTFIELDS => http_build_query($params),
    CURLOPT_RETURNTRANSFER => true,
];

$handle = curl_init();
curl_setopt_array($handle, $opt);
$apiResponse = json_decode(curl_exec($handle), true);
curl_close($handle);

echo "サーバからの応答:\n";
print_r($apiResponse);

実行結果


サーバからの応答:
Array
(
    [status] => success
    [message] => ユーザ: konaの好きな食べ物を、 抹茶アイスに変更しました。
)

DELETE


declare(strict_types=1);

$params = [
    'userId' => 1001,
    'userName' => "kona",
    'food' => '抹茶アイス',
];

$opt = [
    CURLOPT_URL => 'http://localhost:8888/server.php',
    CURLOPT_CUSTOMREQUEST => 'DELETE',
    CURLOPT_POSTFIELDS => http_build_query($params),
    CURLOPT_RETURNTRANSFER => true,
];

$handle = curl_init();
curl_setopt_array($handle, $opt);
$apiResponse = json_decode(curl_exec($handle), true);
curl_close($handle);

echo "サーバからの応答: \n";
print_r($apiResponse);

実行結果


サーバからの応答: 
Array
(
    [status] => success
    [message] => ユーザ: konaの好きな食べ物、抹茶アイスを削除しました。
)

参考書籍

PHP本格入門[下] ~オブジェクト指向設計、セキュリティ、現場で使える実践ノウハウまで

IT  PHP