laravel8でRestfulなCRUDメモアプリAPIを作ってみる。
1, 一分で出来るlaravel api
1 2 |
# laravel本体 composer create-project laravel/laravel api |
routes/api.phpに追記
1 2 3 |
Route::get('/', function () { return 'hello, api'; }); |
getなのでブラウザで大丈夫。文字列が表示されればOK!
http://localhost/api/public/api
最低限のAPIなら、1分で出来たな…。
routes/api.php
routes/web.php
の違いは、urlに/apiがつくだけ?
2, さすがにcontrollerくらいは作ろう
1 |
php artisan make:model Memo -a |
routes/api.phpに記述
1 2 3 4 |
// laravel8から使うコントローラーのuseが必要 use App\Http\Controllers\MemoController; // restfulにしておく Route::Resource('memo', MemoController::class); |
app/Http/Controllers/MemoController.phpのindex()に、返す文字列を記述
http://localhost/api/public/api/memo で表示される事を確認
1 2 3 4 |
public function index() { return 'memo api controller'; } |
3, postでDBにINSERTしたい!
適当なカラムを追加して、php artisan migrate
1 2 3 4 5 6 7 8 9 |
public function up() { Schema::create('memos', function (Blueprint $table) { $table->id(); $table->string('title'); $table->string('content'); $table->timestamps(); }); } |
app/Http/models/Memo.php マス・アサイメントってめんどい…。
1 2 3 4 5 6 |
class Memo extends Model { // id以外のカラムは自由にinsert/updateしてOK! protected $guarded = ['id']; use HasFactory; } |
app/Http/Controllers/MemoController.phpのstore()に、DBのISNERT処理を記述
1 2 3 4 5 |
public function store(Request $request) { Memo::create($request->all()); return "ok"; } |
getはブラウザからurl入力でテスト出来るけど、他のメソッドは無理なのでpostmanを使おう
postしてMySQLにINSERTされていればOK
postしているのに、なぜかgetになる…。
urlの最後にスラッシュがついているとgetにリダイレクトされるみたい・・・なんで?
4, apiのvalidationってどうするの?
titleやcontentを入れないでpostするとエラー画面のhtmlがそのまま返される。
とりあえず、バリデーション入れて、結果をそれっぽいjsonで返すようにしよう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
// useを忘れずに! use Illuminate\Support\Facades\Validator; // 省略して、いきなるクラス名でもOK use Validator; // そもそも円マーク(バックスラッシュ)を頭につければ行けるのでuse不要…? public function store(Request $request) { //バリデーションルールを設定 $validator = \Validator::make($request->all(), [ 'title' => 'required|max:255', 'content' => 'required|max:255', ]); //バリデーションルールにでエラーの場合 if ($validator->fails()) { return response()->json([ 'success' => false, 'message' => 'Insert Failed', 'details' => $validator->errors() ]); } // 問題なければDB登録 Memo::create($request->all()); // jsonで結果を返す return response()->json([ 'success' => true, 'message' => 'Insert Success!', 'details' => $request->all() ]); } |
3, updateとdeleteしたい!
引数の時点でモデルで渡してくれるのは良いけど、存在しないレコードidだとエラー画面の文字列を返すので、昔ながらの$idで対処
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
//public function update(Request $request, Memo $memo) public function update(Request $request, $id) { //バリデーションルールを設定 $request['id'] = $id; $validator = Validator::make($request->all(), [ 'id' => 'required|exists:memos', 'title' => 'required|max:255', 'content' => 'required|max:255', ]); //バリデーションルールにでエラーの場合 if ($validator->fails() ) { return response()->json([ 'success' => false, 'message' => 'Update failed...', 'details' => $validator->errors() ]); } // 問題なければDB更新 $memo = Memo::find($id); $memo->update($request->all()); // jsonで結果を返す return response()->json([ 'success' => true, 'message' => 'Update Success!', 'details' => $request->all() ]); } //public function destroy(Memo $memo) public function destroy($id) { // 存在しないレコードIDだったら if (Memo::where('id', $id)->exists() == false ) { return response()->json([ 'success' => false, 'message' => 'Delete failed...', 'details' => 'Invalid ID' ]); } // 問題なければDB更新 $memo = Memo::find($id); $memo->delete(); // jsonで結果を返す return response()->json([ 'success' => true, 'message' => 'Delete Success!', 'details' => $memo ]); } |
4, 冷静に考えると、一覧(index)や個別(show)の表示がなかったので実装
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
// 全レコード表示 public function index() { // 問題なければjsonで結果を返す return response()->json([ 'success' => true, 'message' => 'List Success!', 'details' => Memo::all() ]); } // 指定されたIDだけ表示 public function show($id) { // 存在しないレコードIDだったら if (Memo::where('id', $id)->exists() == false ) { return response()->json([ 'success' => false, 'message' => 'Show failed...', 'details' => 'Invalid ID' ]); } // 問題なければjsonで結果を返す return response()->json([ 'success' => true, 'message' => 'Show Success!', 'details' => Memo::find($id) ]); } |
5, キーワード検索したいな…。
restfulには検索が無いので、routes/api.phpに追記
1 2 3 4 5 6 7 8 |
// laravel8から使うコントローラーのuseが必要 use App\Http\Controllers\MemoController; // resourceの前に記述しないと、showのmomo/{id}に引っかかってしまう! Route::get('memo/search', [MemoController::class, 'search']); // restfulにしておく Route::Resource('memo', MemoController::class); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
class MemoController extends Controller { public function search(Request $request) { //バリデーションルールを設定 $validator = Validator::make($request->all(), [ 'keyword' => 'required|max:255', ]); //バリデーションルールでエラーの場合 if ($validator->fails()) { return response()->json([ 'success' => false, 'message' => 'Search failed', 'details' => $validator->errors() ]); } // キーワードで検索 $memos = Memo::where('title', 'like', "%$request->keyword%") ->orwhere('content', 'like', "%$request->keyword%")->get(); // 問題なければjsonで結果を返す return response()->json([ 'success' => true, 'message' => 'Search Success!', 'details' => $memos ]); } |
とりあえず、これで一通り出来たかな?