This content originally appeared on Twilio Blog and was authored by Michael Okoh
この記事はMichael Okohがこちらで公開した記事(英語)を日本語化したものです。
ソーシャルネットワークから銀行アプリケーションまで、現代社会は多くのAPIで動いています。本稿では、Laravel PHPを使ってRESTful APIと、それを実装するアプリケーションを構築する方法について学びます。
必要条件
このチュートリアルでは、PHP言語とLaravelフレームワークの基本的な知識と、以下の項目が必要です。
- PHP 7.1以降
- Composer
- MySQL
- Laravel 5.6以降
- Postman
作成するアプリケーションについて
本稿では、学生に関するデータを取り扱うCRUD APIを構築します。CRUDは、Create(作成)、Read(読み取り)、Update(更新)、Delete(削除)を意味します。このAPIには、次のエンドポイントがあります。
GET /api/students
は、すべての学生レコードを返し、GET
リクエストを受け入れます。GET /api/students/{id}
は、学生レコードのid
を参照して学生レコードを返し、GET
リクエストを受け入れます。POST /api/students
は、新しい学生レコードを作成し、POST
リクエストを受け入れます。PUT /api/students/{id}
は、学生レコードのid
を参照して既存の学生レコードを更新し、PUT
リクエストを受け入れます。DELETE /api/students/{id}
は、学生レコードのid
を参照して学生レコードを削除し、DELETE
リクエストを受け入れます。
学生レコードには、name
とcourse
のみが詳細情報として含まれます。これらのエンドポイントの開発が完了したら、エンドポイントを使用して、実際の学生レコードに関するデータを取り扱うアプリケーションを開発します。
Laravelアプリケーションの設定をする
まず、Laravelアプリケーションを作成する必要があります。これを行うには、ターミナルで次のコマンドを実行します。
$ laravel new api-project
次に、以下のコマンドで現在のディレクトリをプロジェクトのルートフォルダに変更します。
$ cd api-project
Laravelサーバーがまだ実行されていない場合は、以下のコマンドでLaravelサーバーを起動します。
$ php artisan serve
アプリケーションにはhttps://localhost:8000からアクセスできます。
次に、以下のコマンドを実行し、アプリケーションの新しいデータベースを作成します。
$ mysql -uroot -p
MySQLで認証する際に、すでにパスワードを設定している場合は、MySQLパスワードを入力するように求められます。次のコマンドを実行し、api-project
という名前の新しいデータベースを作成します。
CREATE DATABASE `api-project`;
移行しながらモデルの作成を進めることができます。これを行うには、次のコマンドを実行します。
$ php artisan make:model Student -m
Student.php
という名前の新しいファイルがapp
ディレクトリに作成されます。
注: ファイルを編集して、対話したいデータベーステーブルと書き込み可能なフィールドを指定する必要があります。
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Student extends Model
{
protected $table = 'students';
protected $fillable = ['name', 'course'];
}
さらに、移行ファイルがdatabase/migrations
ディレクトリに作成され、テーブルが生成されます。移行ファイルを変更し、文字列値を受け入れるname
とcourse
の列を作成します。
...
public function up()
{
Schema::create('students', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('course');
$table->timestamps();
});
}
...
次に、テキストエディタでプロジェクトフォルダを開き、.envファイルを以下のように変更して適切なデータベース認証情報を入力できるようにします。これにより、作成したデータベースにアプリケーションを正しく接続できます。
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=<your-database-name>
DB_USERNAME=<your-database-username>
DB_PASSWORD=<your-database-password>
次に、以下のコマンドを使用して、移行を実行します。
$ php artisan migrate
ルートを設定する
アプリケーションの基本を設定したら、次のコマンドを実行して、APIのメソッドが含まれるコントローラーの作成を進めます。
$ php artisan make:controller ApiController
app\http\controllers
ディレクトリに、ApiController.php
ファイルがあります。以下のメソッドを追加します。
...
class ApiController extends Controller
{
public function getAllStudents() {
// logic to get all students goes here
}
public function createStudent(Request $request) {
// logic to create a student record goes here
}
public function getStudent($id) {
// logic to get a student record goes here
}
public function updateStudent(Request $request, $id) {
// logic to update a student record goes here
}
public function deleteStudent ($id) {
// logic to delete a student record goes here
}
}
routes
ディレクトリに進み、api.php
ファイルを開き、ApiController
で作成済みのメソッドを参照するエンドポイントを作成します。
...
Route::get('students', 'ApiController@getAllStudents');
Route::get('students/{id}', 'ApiController@getStudent');
Route::post('students, 'ApiController@createStudent');
Route::put('students/{id}', 'ApiController@updateStudent');
Route::delete('students/{id}','ApiController@deleteStudent');
注: api.php
のすべてのルートには、デフォルトで先頭に/api
が付きます。
学生レコードを作成する
ApiController
のcreateStudent
メソッドを使います。
public function createStudent(Request $request) {
// logic to create a student record goes here
}
エンドポイントに渡されるデータを取得するには、Laravelリクエストクラスを使用します。エンドポイントでは、string
型のname
とstring
型のcourse
も必要になります。データを正常に取得できたら、データベースにデータを保存します。
...
use App\Student;
class ApiController extends Controller
{
...
public function createStudent(Request $request) {
$student = new Student;
$student->name = $request->name;
$student->course = $request->course;
$student->save();
return response()->json([
"message" => "student record created"
], 201);
}
...
}
上記のスニペットでは、データベースのstudents
テーブルと対話するStudent
モデルをインポートします。createStudent
メソッドでは、メソッドパラメーターの新しいRequest
オブジェクトをインスタンス化し、続いてStudent
オブジェクトをインスタンス化します。最後に、$student->
ごとに同等のリクエストが取得され、保存されます。
操作が成功すると、student record created
メッセージとレスポンスコード201
でJSONレスポンスがAPIユーザーに返信されます。
このメソッドは、routes/api.php
にあるルートのファイルにあらかじめ定義したため、すでに/api/students
に紐付けられています。
...
Route::post('students, 'ApiController@createStudent');
...
テストする
テストする前に、アプリケーションが実行されていることを確認します。前述のように、ビルトインのコマンドを使用できます。
$ php artisan serve
または、PHPアプリケーションのプロキシパスを作成するためのツールであるValetを使用して、アプリケーションをローカルでテストするための.test
または.dev
ドメインを指定できます。
このエンドポイントをテストするには、Postmanを開き、http://localhost:8000/api/students
またはhttp://<folder-name>/api/students
(Valetを使用する場合)にPOST
リクエストを実行します。次のスクリーンショットに示すように、form-data
オプションを選択し、次の値を渡します。
成功メッセージと201
レスポンスコードが返されれば正常です。次のタスク用に、データベースに後数件、レコードを追加してみてください。
すべての学生レコードを返す
次に、ApiController
のgetAllStudents
メソッドを編集します。
public function getAllStudents() {
// logic to get all students goes here
}
すでにインポートしたStudent
モデルを使用し、データベースのすべての学生を返すためのシンプルなEloquentクエリを作成します。
class ApiController extends Controller
{
public function getAllStudents() {
$students = Student::get()->toJson(JSON_PRETTY_PRINT);
return response($students, 200);
}
...
}
Eloquentクエリは->toJson(JSON_PRETTY_PRINT);
で終わります。Eloquentで返されるオブジェクトデータが、適切に書式設定されたJSONにシリアル化されます。JSONはレスポンスコード200
と共に返されます。
このメソッドは、routes/api.php
にあるルートのファイルにあらかじめ定義したため、すでに/api/students
ルートに紐付けられています。
...
Route::get('students', 'ApiController@getAllStudents');
...
テストする
アプリケーションがバックグラウンドで実行されている場合は、Postmanの/api/students
エンドポイントにGET
リクエストを実行します。
上のスクリーンショットに示すように、エンドポイントはデータベースのすべての学生レコードを返します。
学生レコードを返す
単一の学生レコードのみを返すためのエンドポイントを作成します。ApiController
のgetStudent
メソッドを使います。
public function getStudent($id) {
// logic to get a student record goes here
}
学生レコードのid
で学生レコードを取得し、これに対して、その学生レコードのid
で学生レコードを返すためのEloquentクエリを作成します。
...
class ApiController extends Controller
{
...
public function getStudent($id) {
if (Student::where('id', $id)->exists()) {
$student = Student::where('id', $id)->get()->toJson(JSON_PRETTY_PRINT);
return response($student, 200);
} else {
return response()->json([
"message" => "Student not found"
], 404);
}
}
...
}
前述のスニペットは、指定したid
の学生レコードが存在するかどうかをチェックします。存在する場合は、Eloquentを使用してデータベースにクエリを実行し、id
と一致するレコードをJSON形式にて、レスポンスレコード200
と共に返します。指定したid
がデータベースで見つからない場合、student not found
メッセージと404
レスポンスコードを返します。
このメソッドは、routes/api.php
にあるルートのファイルにあらかじめ定義したため、すでに/api/students/{id}
ルートに紐付けられています。
...
Route::get('students/{id}', 'ApiController@getStudent');
...
テストする
Postmanを開き、/api/students/{id}
エンドポイントにGET
リクエストを実行します。{id}
は、データベースの既存レコードのid
にします。
上のスクリーンショットに示すように、http://api-project.test/api/students/3
にリクエストを実行し、そのid
に割り当てられた学生の詳細が返されました。次に、存在しない学生レコードをリクエストします。
上のスクリーンショットに示すように、id
が100
の存在しない学生レコードの詳細を要求するリクエストがエンドポイントに送信されました返されました。APIが正常に実行され、エラーメッセージと404
ステータスコードが返されました。
学生レコードを更新する
次に、既存の学生レコードの詳細を更新するためのエンドポイントを作成します。ApiController
のupdateStudent
メソッドを使います。
public function updateStudent(Request $request, $id) {
// logic to update a student record goes here
}
これを行うには、更新しようとしているレコードが存在するかどうかを確認する必要があります。存在する場合、指定したid
と一致するレコードが更新され、ステータスコード204
が返されます。存在しない場合、レコードが見つからないことを示すメッセージとステータスコード404
が返されます。
public function updateStudent(Request $request, $id) {
if (Student::where('id', $id)->exists()) {
$student = Student::find($id);
$student->name = is_null($request->name) ? $student->name : $request->name;
$student->course = is_null($request->course) ? $student->course : $request->course;
$student->save();
return response()->json([
"message" => "records updated successfully"
], 200);
} else {
return response()->json([
"message" => "Student not found"
], 404);
}
}
name
またはcourse
のいずれかの属性のみを更新する必要がある場合に備えて、検証を追加しています。リクエストを受け取ると、name
またはcourse
がnull
かどうかをチェックします。null
の場合は、データベースのレコードをを既存の値に置き換えます。null
でない場合は、null
が新しい値として渡されます。これはすべて三項演算子を使用して実行されます。
注: 三項演算子の形式はcondition ? true : false
です。
このメソッドは、routes/api.php
にあるルートのファイルにあらかじめ定義したため、すでに/api/students/{id}
ルートに紐付けられています。
...
Route::put('students/{id}', 'ApiController@updateStudent');
...
テストする
このエンドポイントをテストするには、/api/students/1
にGET
リクエストを実行し、id
が1
の学生レコードの詳細を返します。
次のようなレコードが返されます。
[
{
"id": 1,
"name": "Michael Okoh",
"course": "Computer Science",
"created_at": " 14:11:17",
"updated_at": " 14:11:17"
}
]
次に、/api/students/1
にPUT
リクエストを実行し、course
を「Software Engineering」に変更します。PUT
リクエストを実行するには、form-data
経由でJSONペイロードを渡します。さらに、name
の値をTrojan Okoh
、course
の値を「Software Engineering」に変更します。
{
"name": "Trojan Okoh",
"course": "Software Engineering"
}
前述のスニペットはJSONペイロードで、レコードの更新に使用します。次に示すように、Postmanを開いてraw
に変更し、型をJSON(application/json)
に変更します。
次に、JSONペイロードをテキスト領域に貼り付け、エンドポイントにPUT
リクエストを送信します。
上のスクリーンショットに示すように、エンドポイントが成功メッセージを返しました。次に、/api/students/1
にGETリクエストを実行し、レコードが実際に更新されたかどうかを確認します。
学生レコードを削除する
最後に、学生レコードを削除するには、ApiController
のdeleteStudent
メソッドを使います。
public function deleteStudent ($id) {
// logic to delete a student record goes here
}
Eloquentを使用して、削除リクエストの対象となるレコードのid
が存在するかどうかを確認します。存在する場合は、レコードを削除します。存在しない場合は、not found
メッセージと404
ステータスコードを返します。
...
class ApiController extends Controller
{
...
public function deleteStudent ($id) {
if(Student::where('id', $id)->exists()) {
$student = Student::find($id);
$student->delete();
return response()->json([
"message" => "records deleted"
], 202);
} else {
return response()->json([
"message" => "Student not found"
], 404);
}
}
}
このメソッドは、routes/api.php
にあるルートのファイルにあらかじめ定義したため、すでに/api/students/{id}
ルートに紐付けられています。
...
Route::delete('students/{id}', 'ApiController@deleteStudent');
テストする
このエンドポイントをテストするには、/api/students
エンドポイントにGET
リクエストを実行し、データベースに存在するすべてのレコードをリストする必要があります。
次に、/api/students/{id}
にDELETE
リクエストを実行します。{id}
は、削除リクエストをするレコードのid
です。ここでは、テスト目的でid
が2
のレコードを削除します。
リクエストが受け入れられたことを意味するステータスコード202
と成功メッセージがエンドポイントから返されました。レコードが実際に削除されたかどうかを確認するには、/api/students
エンドポイントにGET
リクエストを実行し、データベースにあるすべての学生レコードをリストします。
上のスクリーンショットに示すように、id
が2
のレコードはもう存在しません。また、/api/students/{id}
エンドポイントにGET
リクエストを実行し、id
が2
のレコードをリクエストして確認することもできます。レコードが見つからなかったことを示す404
が返されます。
まとめ
最後に、本稿でご紹介した重要なファイルの内容を確認します。
app\http\controllers\ApiController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Student;
class ApiController extends Controller
{
public function getAllStudents() {
$students = Student::get()->toJson(JSON_PRETTY_PRINT);
return response($students, 200);
}
public function createStudent(Request $request) {
$student = new Student;
$student->name = $request->name;
$student->course = $request->course;
$student->save();
return response()->json([
"message" => "student record created"
], 201);
}
public function getStudent($id) {
if (Student::where('id', $id)->exists()) {
$student = Student::where('id', $id)->get()->toJson(JSON_PRETTY_PRINT);
return response($student, 200);
} else {
return response()->json([
"message" => "Student not found"
], 404);
}
}
public function updateStudent(Request $request, $id) {
if (Student::where('id', $id)->exists()) {
$student = Student::find($id);
$student->name = is_null($request->name) ? $student->name : $request->name;
$student->course = is_null($request->course) ? $student->course : $request->course;
$student->save();
return response()->json([
"message" => "records updated successfully"
], 200);
} else {
return response()->json([
"message" => "Student not found"
], 404);
}
}
public function deleteStudent ($id) {
if(Student::where('id', $id)->exists()) {
$student = Student::find($id);
$student->delete();
return response()->json([
"message" => "records deleted"
], 202);
} else {
return response()->json([
"message" => "Student not found"
], 404);
}
}
}
routes\web.php
<?php
use Illuminate\Http\Request;
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
Route::get('students', 'ApiController@getAllStudents');
Route::get('students/{id}', 'ApiController@getStudent');
Route::post('students, 'ApiController@createStudent');
Route::put('students/{id}', 'ApiController@updateStudent');
Route::delete('students/{id}', 'ApiController@deleteStudent');
app\Student.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Student extends Model
{
protected $table = 'students';
protected $fillable = ['name', 'course'];
}
Laravelを使用して、簡単なCRUD RESTful APIを構築できました。本稿では、Laravelを使ったCRUD RESTful APIの構築の基本について説明しましたが、リクエストの検証とAPIセキュリティについては取り上げませんでした。ぜひ、本稿をもとにリクエスト検証も試してみてください。
Twitter: [@ichtrojan](https://twitter.com/ichtrojan)
GitHub: [@ichtrojan](https://github.com/ichtrojan)
メール: michael@okoh.co.uk
This content originally appeared on Twilio Blog and was authored by Michael Okoh

Michael Okoh | Sciencx (2022-02-25T05:04:11+00:00) Laravel PHPでRESTful APIを構築する方法. Retrieved from https://www.scien.cx/2022/02/25/laravel-php%e3%81%a7restful-api%e3%82%92%e6%a7%8b%e7%af%89%e3%81%99%e3%82%8b%e6%96%b9%e6%b3%95/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.