PHP

Laravel5.8 RESTful API

Laravel

Laravelは簡単にRestful APIを実装できるようになっています。

 

バージョン

  • PHP 7.1.27
  • Laravel 5.8.8

 

実装のポイント

コントローラを作る時に–resourceオプション

$ php artisan make:controller MonsterController --resource

 

ルートにresourceのメソッドを指定する

$ vi ./routes/api.php

Route::resource('monsters', 'MonsterController');

これだけです。

 

RESTfulの特徴

メソッドで動作を変化させるシンプル設計

  • 一覧取得 index()
    GET /api/monsters/
  • IDを指定して取得
    GET /api/monsters/{id}
  • 新規追加
    POST /api/monsters/
  • 更新
    PUT /api/monsters/
  • IDを指定して削除
    DELETE /api/monsters/{id}

URLはそろえてHTTPメソッドで動作を変化させる

ステートレス

セッションなどの状態を管理せず、リクエストで必ず処理が完了する

 

URLの設計

  • https://api.example.net/
    apiとすぐにわかるURLにする。
  • 拡張子をつけてはいけない
  • URLが変わることがあってはいけない
  • URLは複数名刺にする、バージョンを含める、動詞はつけない
    http://api.example.net/v1/monsters/

// 今回の記事は良くないURLになっています。

 

モデルの作成

$ mkdir ./app/Models
$ php artisan make:model Models/Monster -m

Model created successfully.
Created Migration: 2019_03_31_075556_create_monsters_table

 

プライマリキーの設定

 

$ vi ./app/Models/Monster.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Monster extends Model
{
    protected $primaryKey = 'monster_id';
}

 

テーブルの定義

 

$ vi ./database/migrations/2019_03_31_082838_create_monsters_table.php


<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateMonstersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('monsters', function (Blueprint $table) {
            $table->bigIncrements('monster_id');
            $table->string('name');
            $table->string('voice');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('monsters');
    }
}

 

シーダファイルの作成

 

$ php artisan make:seeder MonstersTableSeeder
$ vi ./database/seeds/MonstersTableSeeder.php


<?php

use Illuminate\Database\Seeder;

class MonstersTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        DB::table("monsters")->insert([
            "monster_id" => 1,
            "name"       => "komaさん",
            "voice"      => "もんげぇ",
            "created_at" => new DateTime(),
            "updated_at" => new DateTime()
        ]);

        DB::table("monsters")->insert([
            "monster_id" => 1,
            "name"       => "Nyanchuuさん",
            "voice"      => "ミーだにゃぁ",
            "created_at" => new DateTime(),
            "updated_at" => new DateTime()
        ]);
    }
}

 

レコードの削除+テーブルの作成

 

$ php artisan migrate:refresh --seed

 

シーダファイルによるインサート

$ php artisan db:seed --class=MonstersTableSeeder

 

ミドルウェアの作成

 

JSONの日本語文字化け防止

(外部サイト:https://nextat.co.jp/staff/archives/203)

$ php artisan make:middleware UnescapeJsonResponse
$ vi ./app/Http/Middleware/UnescapeJsonResponse.php


<?php

namespace App\Http\Middleware;

use Closure;

use Symfony\Component\HttpFoundation\JsonResponse;

class UnescapeJsonResponse
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $response = $next($request);

        // JSON以外はそのまま
        if (!$response instanceof JsonResponse) {
            return $response;
        }

        // エンコードオプションを追加して設定し直す
        $newEncodingOptions = $response->getEncodingOptions() | JSON_UNESCAPED_UNICODE;
        $response->setEncodingOptions($newEncodingOptions);

        return $response;
    }
}

 

Laravel Kernelに追加

$ vi ./app/Http/Kernel.php

    protected $routeMiddleware = [
        'auth' => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
        'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
        
        ※下記を追加
        
        'UnescapeJsonResponse' => \App\Http\Middleware\UnescapeJsonResponse::class,
    ];

 

コントローラの作成

 

$ php artisan make:controller MonsterController --resource

 

初期状態確認

$ cat ./app/Http/Controllers/MonsterController.php


<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class MonsterController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        //
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        //
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        //
    }
}

 

コントローラ内容変更

$ vi ./app/Http/Controllers/MonsterController.php



<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Monster;

class MonsterController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function __construct()
    {
        $this->middleware('UnescapeJsonResponse');
    }

    public function index()
    {
        $items = Monster::all();
        return response()->json($items);
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        $this->validate($request, [
            'name'   => 'required|max:255',
            'voice'  => 'required|max:255',
        ]);
        $monster = new Monster();
        $monster->name = $request->name;
        $monster->voice = $request->voice;
        $monster->save();
        return response()->json();
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        $item = Monster::find($id);
        return response()->json($item);
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        $this->validate($request, [
            'name'   => 'required|max:255',
            'voice'  => 'required|max:255',
        ]);
        $monster = Monster::find($id);
        $monster->name = $request->name;
        $monster->voice = $request->voice;
        $monster->save();
        return response()->json();
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy(Request $request, $id)
    {
        $monster = Monster::find($id);
        $monster->delete();
        return response()->json();
    }
}

 

 

ルート設定

 

$ vi ./routes/api.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::resource('monsters', 'MonsterController');

 

ルーティング確認

$ php artisan route:list
+--------+-----------+-----------------------------+------------------+------------------------------------------------+--------------------------+
| Domain | Method    | URI                         | Name             | Action                                         | Middleware               |
+--------+-----------+-----------------------------+------------------+------------------------------------------------+--------------------------+
|        | GET|HEAD  | /                           |                  | Closure                                        | web                      |
|        | GET|HEAD  | api/monsters                | monsters.index   | App\Http\Controllers\MonsterController@index   | api,UnescapeJsonResponse |
|        | POST      | api/monsters                | monsters.store   | App\Http\Controllers\MonsterController@store   | api,UnescapeJsonResponse |
|        | GET|HEAD  | api/monsters/create         | monsters.create  | App\Http\Controllers\MonsterController@create  | api,UnescapeJsonResponse |
|        | GET|HEAD  | api/monsters/{monster}      | monsters.show    | App\Http\Controllers\MonsterController@show    | api,UnescapeJsonResponse |
|        | PUT|PATCH | api/monsters/{monster}      | monsters.update  | App\Http\Controllers\MonsterController@update  | api,UnescapeJsonResponse |
|        | DELETE    | api/monsters/{monster}      | monsters.destroy | App\Http\Controllers\MonsterController@destroy | api,UnescapeJsonResponse |
|        | GET|HEAD  | api/monsters/{monster}/edit | monsters.edit    | App\Http\Controllers\MonsterController@edit    | api,UnescapeJsonResponse |
|        | GET|HEAD  | api/user                    |                  | Closure                                        | api,auth:api             |
+--------+-----------+-----------------------------+------------------+------------------------------------------------+--------------------------+

 

 

index()確認

http://IPアドレス/api/monsters

 

show()確認

http://IPアドレス/api/monsters/2

 

Amazonおすすめ

iPad 9世代 2021年最新作

iPad 9世代出たから買い替え。安いぞ!🐱 初めてならiPad。Kindleを外で見るならiPad mini。ほとんどの人には通常のiPadをおすすめします><

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)