LoginSignup
1
0

【簡単】LaravelでAPIの実装

Last updated at Posted at 2024-02-13

はじめに

次のタスクが、久しぶりにLaravel+APIをさわるので復習を兼ねて備忘録として残します。

補足

開発環境

  • Mac
  • PHP:version 8.2.11
  • Laravel:version 10.42.0
  • Composer:version 2.2.4

実装

プロジェクトを作成する

  • composerを使用してプロジェクトを作成する
$ composer create-project laravel/laravel laravel-api-test
  • サーバーを起動できるか確認
$ cd laravel-api-test
$ php artisan serve
  • 下記の画面になっていればOK
    スクリーンショット 2024-01-27 18.07.41.png

  • Blog記事を作る想定で、マイグレーションのモデルを作成

$ php artisan make:model Blog -m
  • 下記のようにマイグレーションに失敗する場合

スクリーンショット 2024-01-28 20.06.30.png

  • Laravelとmysqlの接続が上手くいっていないので、.envファイルの設定を見直す
.env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=xxx
DB_PASSWORD=xxx
  • 見直したあとにマイグレーションコマンド実行
$ php artisan migrate
  • createできていることを確認

スクリーンショット 2024-01-30 9.15.34.png

コントローラーを作成

$ php artisan make:controller ApiBlogController --model=Blog
  • 処理を追加
ApiBlogController.php
<?php

namespace App\Http\Controllers;

use App\Http\Requests\StoreBlogRequest;
use App\Models\Blog;
use Illuminate\Http\Request;

class ApiBlogController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index()
    {
        $blogs = Blog::all();
        return response()->json([
            'status' => true,
            'blogs' => $blogs
        ], 200);
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(StoreBlogRequest $request)
    {
        $blog = Blog::create($request->all());
        return response()->json([
            'status'=> true,
            'message'=>'Blog Created successfully!',
            'blog'=> $blog
        ], 201);
    }

    /**

     * Display the specified resource.
     */
    public function show($id)
    {
        $blogs = Blog::find($id);
        if($blogs){
            return response()->json([
                'message'=> 'Blog found',
                'data' => $blogs
            ], 200);
        } else {
            return response()->json([
                'message'=> 'Blog not found',
            ], 404);
        }

    }

    /**
     * Update the specified resource in storage.
     */
    public function update(Request $request, $id)
    {
        $update = [
            'title' => $request->title,
            'article' => $request->article
        ];
        $blog =  Blog::where('id', $id)->update($update);
        $blogs = Blog::all();
        if ($blog) {
            return response()->json([
                'message'=> 'Blog update',
                'data' => $blogs
            ], 200);
        } else {
            return response()->json([
                'message' => 'Blog not found',
            ], 404);
        }
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy($id)
    {
        $blog = Blog::where('id', $id)->delete();
        if ($blog) {
            return response()->json([
                'message' => 'Blog deleted successfully',
            ], 200);
        } else {
            return response()->json([
                'message' => 'Blog not found',
            ], 404);
        }
    }
}


バリデーション追加のため、StoreBlogRequest作成

$ php artisan make:request StoreBlogRequest
StoreBlogRequest.php
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\ValidationException;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Http\Exceptions\HttpResponseException;

class StoreBlogRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     */
    public function authorize(): bool
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
     */
    public function rules(): array
    {

        return [
            'title' => 'required|string|max:20',
            'article' => 'required|string|max:255'
        ];
    }

    /**
     * Get error messages for defined validation rules
     *
     * @return array<string, string>
     */
    public function messages(): array
    {
        return [
            'title.required' => 'タイトルは必須です',
            'article.required' => '記事は必須です',
            'title.max' => 'タイトルは20文字以内です',
            'article.max' => '記事255文字以内です',
        ];
    }


    protected function failedValidation(Validator $validator)
    {
        $errors = (new ValidationException($validator))->errors();
        throw new HttpResponseException(response()->json([
            'message' => 'Failed validation',
            'errors' => $errors,
        ], 400, [], JSON_UNESCAPED_UNICODE));
    }
}

route作成

api.php
<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use app\Http\Controllers\ApiBlogController;

/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider and all of them will
| be assigned to the "api" middleware group. Make something great!
|
*/

Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
    return $request->user();
});

Route::apiResource('blogs', ApiBlogController::class);

  • 確認
$ php artisan route:list

スクリーンショット 2024-02-08 22.15.27.png

動作確認

  • 下記でサーバー起動させた状態で、Postmanで動作確認する
$ php artisan serve

新規作成

  • 下記の内容を作成する
key value
title 記事タイトル
article 記事の内容

スクリーンショット 2024-02-12 20.52.00.png

スクリーンショット 2024-02-12 20.52.10.png

一覧を確認

  • 下記のように入力し、GETで取得

スクリーンショット 2024-02-12 21.03.11.png

特定のidを取得

スクリーンショット 2024-02-12 20.51.29.png

特定のidの情報を更新

  • PUTでidを指定し、内容更新されているのを確認

スクリーンショット 2024-02-12 21.05.00.png

レコードの削除

  • id2が削除されているのを確認

スクリーンショット 2024-02-12 21.06.41.png

スクリーンショット 2024-02-12 21.06.53.png

ステータスコードについて補足

ステータスコード 説明
200 リクエストが成功したことを示す。 (操作の結果を表すリソースがメッセージ本文で送信される)
201 リクエストは成功し、その結果新たなリソースが作成されたことを示す。
204 リクエストに対して送信するコンテンツはありませんが、ヘッダーは有用であることを示す。リクエスト成功して、返す値がない場合はこちらの方が適切
400 構文が無効であるためサーバーがリクエストを理解できないことを示す。
404 サーバーがリクエストされたリソースを発見できないことを示す。 通信先が有効であるものの、リソース自体が存在しないことを意味することがある。

Eloquentリソースを使用してみる

  • APIの実装で一覧と詳細のデータを返す時にこのリソースを使用すると楽みたいなので、実装して検証する。リソースクラスを作成
$ php artisan make:resource BlogResource
  • BlogResourceへ追記
BlogResource.php
<?php

namespace App\Http\Resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

class BlogResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @return array<string, mixed>
     */
    public function toArray(Request $request): array
    {
        return [
            'id' => $this->id,
            'title' => $this->title,
            'article' => $this->article,
            'created_at' => $this->created_at,
            'updated_at' => $this->updated_at,
        ];    }
}

  • コントローラー編集
<?php

namespace App\Http\Controllers;

use App\Http\Requests\StoreBlogRequest;
use App\Models\Blog;
use Illuminate\Http\Request;
use App\Http\Resources\BlogResource;

class ApiBlogController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index()
    {
    $blogs = Blog::all();
    return response()->json([
        'status' => true,
        'blogs' => BlogResource::collection($blogs)
    ], 200);
    }

(略)

    /**

     * Display the specified resource.
     */
    public function show($id)
    {
        $blog = Blog::find($id);
        if ($blog) {
            return response()->json([
                'status' => true,
                'blog' => new BlogResource($blog)
            ], 200);
        } else {
            return response()->json([
                'message' => 'Blog not found',
            ], 404);
        }
    }
    (略)
}


  • 一覧取得

スクリーンショット 2024-02-17 19.50.23.png

  • 詳細取得

スクリーンショット 2024-02-17 19.52.39.png

どちらも取得できていること確認。Eloquentリソース使用したことなかったけど、使い勝手はよさそう。

まとめ

Web APIの設計のベストプラクティスなど、色々考慮することもありますが、今回は簡単にLaravel+APIの実装を復習しました!今後テストコードやAPI認証の実装も追加していく予定です。

追記

参考

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0