LoginSignup
3
4

More than 5 years have passed since last update.

Lumenで継承を使ってAPIをサクッと作ってみた

Posted at

LumenでAPIを作ったんですが、APIってCRUDベースで作れば事足りる機能がほとんどかなと思い、継承を使ってサクッと作ってみました。
継承を使えば記述量もぐっと減るし、うまく使えれば大変便利です
それにバシーっと決まれば個人的にめっさ気持ち良いですよね

構成

アセット 1.png

上記図の通り親クラスとなる ApiController に具体的な処理を書き
それを継承するようにします
継承先はControllerとModelがあり紐づいてます

CRUDをベースとなるコントローラに作成する

メソッドはCRUDを基とし以下のようになっています

  • index→一覧
  • show→詳細
  • store→登録
  • update→更新
  • destroy→削除
app/Http/Controllers/ApiController.php
<?php

namespace App\Http\Controllers;

use Laravel\Lumen\Routing\Controller as BaseController;
use Illuminate\Http\Request;

class ApiController extends BaseController
{
    protected static $model = "";

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


    public function show($id = 0)
    {
        if(! $id) {
            $response["status"] = "ng";
            $response["messages"] = "引数が不正です";

            return response()->json($response);
        }
        $response = static::$model::find($id);

        if(count($response) < 1) {
            $response["status"] = "ng";
            $response["messages"] = "情報が見つかりません";

            return response()->json($response);    
        }

        $response["status"] = "ok";
        return response()->json($response);
    }


    public function store(Request $request)
    {
        $validator = static::$model::validation($request);

        $response = [];
        if ($validator->fails()) {
            $response["status"] = "ng";
            $response["messages"] = $validator->errors()->all();

            return response()->json($response);
        }


        static::$model::create($request->all());

        $response["status"] = "ok";
        return response()->json($response);
    }


    public function update(Request $request, $id)
    {
        $updates = $request->all();
        unset($updates['api_key']);

        $response = false;
        $response = static::$model::where('id', '=', $id)->update($updates);

        if ($response === 0) {
            $response["status"] = "ng";
            $response["messages"] = "パラメータが不正です";

            return response()->json($response);
        }

        $response["status"] = "ok";
        return response()->json($response);
    }


    public function destroy($id)
    {
        $result = static::$model::destroy($id);
        if ($result === 0) {
            $response["status"] = "ng";
            $response["messages"] = "パラメータが不正です";

            return response()->json($response);
        }

        $response["status"] = "ok";
        return response()->json($response);
    }
}

HTTPレスポンスコードの定義してへんやんとかページネーションは?とかのツッコミは一旦なしで

モデルの定義

    protected static $model = "";

上記の通り、モデルは継承先で定義するため、親クラスでは空で設定します

バリデーションの定義

<?php

namespace App\Http\Controllers;

use Laravel\Lumen\Routing\Controller as BaseController;
use Illuminate\Http\Request;

class ApiController extends BaseController
{
    省略        

    public function store(Request $request)
    {
        $validator = static::$model::validation($request);

        $response = [];
        if ($validator->fails()) {
            $response["status"] = "ng";
            $response["messages"] = $validator->errors()->all();

            return response()->json($response);
        }


        static::$model::create($request->all());

        $response["status"] = "ok";
        return response()->json($response);
    }
    省略
}

$validator = static::$model::validation($request);

バリデーションもモデル側で定義することにより継承をやりやすくしております

モデルの定義

app/Company.php
<?php namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Validator;

class Company extends Model 
{
    protected $table = 'companies';
    protected $fillable = ['name'];

    public static function validation($request)
    {
        return Validator::make($request->all(), [
            'name' => 'required|max:256|unique:companies',
        ]);
    }
}

とりあえずCompanyモデルを例としています
上記の通りバリデーションを書いてます

LumenはデフォルトでModelディレクトリがないのでこのパスになってますが、Modelディレクトリ作っても良いかもですね。

コントロラーの定義

<?php

namespace App\Http\Controllers;

use App\Company;

class CompanyController extends ApiController
{
    protected static $model = "App\Company";
}

モデルと同様にCompanyコントローラを例としています

最初に作成した ApiController を継承しています
そして$modelをComapnyモデルを使うように上書きしています

一点注意としてクラス名を動的に設定する場合はnamespaceを含め設定する必要があります

確認

これでAPIの作成は終わったのでcurlなりPostmanなりで
ドメイン/company/
ドメイン/company/storeにアクセスし正常に動作すれば完成です

コントロラーを増やしたければCompanyを基にモデルとコントロラーを作成すれば簡単に増やせます

以上です

3
4
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
3
4