Lumen で RESTful API を作ってみた
つくるもの
- 記事(posts)の取得、新規作成、更新、削除を行える API をつくる。
- Laravel の Resource Controllers / Resource Route をまねる。
Lumen では、Laravel の
Route::resource('photo', 'PhotoController');
に対応していないため、Resource Controllers / Resource Route の部分は自作する必要がある。
作成した API のルーティングはこんな感じ。
HTTPメソッド | パス | アクション |
---|---|---|
GET | /api/v1/post | index() |
POST | /api/v1/post | store() |
GET | /api/v1/post/{id} | show() |
PUT | /api/v1/post/{id} | update() |
DELETE | /api/v1/post/{id} | destroy() |
ちなみに全ソースコートはここ。
スポンサーリンク
前提
- Lumen 5.3
Lumen コマンドで新規アプリケーション作成
Lumenコマンド で 新規アプリケーションを作成する。
Lumenコマンドのインストール方法はこちら。
プロジェクトディレクトリに移動。
$ cd /var/www/html
アプリケーション名を mylumen とし、Lumenコマンドで新規プロジェクト作成。
$ lumen new mylumen
アプリケーションの作成が終わったらアプリケーションディレクトリに移動しておく。
$ cd mylumen
次に .env.example をコピーして .env を作成する。
APP_KEY
は、
$ php -r "require 'vendor/autoload.php'; echo str_random(32).PHP_EOL;"
で吐き出された値を設定する。
APP_ENV=local APP_DEBUG=true APP_KEY=[your app key] APP_TIMEZONE=Asia/Tokyo DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=mylumen DB_USERNAME=[your db user name] DB_PASSWORD=[your db pass] CACHE_DRIVER=memcached QUEUE_DRIVER=sync
最後に、Facade と Eloquent を使用可能にするため、
bootstrap/app.php
の
// $app->withFacades(); // $app->withEloquent();
部分のコメントアウトを外しておく。
DB の作成
sql で mylumen データベースを作成する。
CREATE DATABASE mylumen;
次に、Lumen の Migrate機能を使用して postsテーブルを作成する。
$ php artisan make:migration create_posts_table --create posts
database/migrations
ディレクトリ以下に [現在日時]_create_posts_table.php
という名前のマイグレートファイルが作成されるので、
up()
内を下記のように修正する。
public function up() { Schema::create('posts', function (Blueprint $table) { $table->increments('id'); $table->string('name'); $table->string('title'); $table->text('text'); $table->timestamps(); }); }
テーブル定義ができたら、マイグレートを実行してテーブルを作成する。
$ php artisan migrate
テーブルができた!
mysql> desc posts; +------------+------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+------------------+------+-----+---------+----------------+ | id | int(10) unsigned | NO | PRI | NULL | auto_increment | | name | varchar(255) | NO | | NULL | | | title | varchar(255) | NO | | NULL | | | text | text | NO | | NULL | | | created_at | timestamp | YES | | NULL | | | updated_at | timestamp | YES | | NULL | | +------------+------------------+------+-----+---------+----------------+
最後に、postsテーブルに適当なダミーデータを流し込んでおく。
INSERT INTO posts (`name`, `title`, `text`, `created_at`, `updated_at`) values('Alex', 'dummy title.', 'dummy text.dummy text.dummy text.dummy text.', NOW(), NOW()), ('Jane', 'example title.', 'example text.example text.example text.example text.', NOW(), NOW()), ('Tonny', 'test title.', 'test text.test text.test text.test text.', NOW(), NOW());
mysql> select * from posts\G *************************** 1. row *************************** id: 1 name: Alex title: dummy title. text: dummy text.dummy text.dummy text.dummy text. created_at: 2017-01-17 10:57:03 updated_at: 2017-01-17 10:57:03 *************************** 2. row *************************** id: 2 name: Jane title: example title. text: example text.example text.example text.example text. created_at: 2017-01-17 10:57:03 updated_at: 2017-01-17 10:57:03 *************************** 3. row *************************** id: 3 name: Tonny title: test title. text: test text.test text.test text.test text. created_at: 2017-01-17 10:57:03 updated_at: 2017-01-17 10:57:03
モデルの作成
posts テーブルを扱うためのモデルを作成する。
ディレクトリは app/Post.php
とし、新規ファイルを作成して下記のコードを記述する。
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Post extends Model { protected $fillable = ['name', 'title', 'text']; }
Route の作成
Route は routes/web.php
に定義されている。
今回、Laravel の Resource Route のようなことをしたいため、
routes 内に function を定義し、それを使ってルーティングを行っていく。
<?php /* |-------------------------------------------------------------------------- | Application Routes |-------------------------------------------------------------------------- | | Here is where you can register all of the routes for an application. | It's a breeze. Simply tell Laravel the URIs it should respond to | and give it the controller to call when that URI is requested. | */ $app->get('/', function () use ($app) { return $app->version(); }); $app->group(['prefix' => 'api/'.env('API_VERSION', 'v0')], function($app) { resource('post', 'PostController'); }); function resource($uri, $controller) { global $app; $app->get($uri, $controller.'@index'); $app->post($uri, $controller.'@store'); $app->get($uri.'/{id}', $controller.'@show'); $app->put($uri.'/{id}', $controller.'@update'); $app->delete($uri.'/{id}', $controller.'@destroy'); }
Resource Route に限らず、このように共通化された route を使うことで、 各 Controller の メソッド も共通化でき便利。
また、$app->group(['prefix' => 'api/'.env('API_VERSION', 'v0')], function($app)
の部分で、
api のバージョンを .env
ファイルに記載するよう変更しているため、.env
に
API_VERSION=v1
を付け加える。
これで以下のようなルーティングになる。
HTTPメソッド | パス | アクション |
---|---|---|
GET | /api/v1/post | index() |
POST | /api/v1/post | store() |
GET | /api/v1/post/{id} | show() |
PUT | /api/v1/post/{id} | update() |
DELETE | /api/v1/post/{id} | destroy() |
Controller の作成
Resource Route っぽい Resource Controller を作成する。
ファイルは app/Http/Controllers/PostController.php
ちなみに、Postmanなどで動作確認する場合は、Content-Type を
POST : form-data
PUT : x-www-form-urlencoded
に設定する。
<?php namespace App\Http\Controllers; use Laravel\Lumen\Routing\Controller as BaseController; use Illuminate\Http\Request; use App\Post; class PostController extends BaseController { /** * Display a listing of the resource. * * @return Response */ public function index() { $response = Post::all(); return response()->json($response); } /** * Store a newly created resource in storage. * * @param Request $request * @return Response */ public function store(Request $request) { $response = Post::create($request->all()); return response()->json($response); } /** * Display the specified resource. * * @param int $id * @return Response */ public function show($id) { $response = Post::find($id); return response()->json($response); } /** * Update the specified resource in storage. * * @param Request $request * @param int $id * @return Response */ public function update(Request $request, $id) { $updates = $request->all(); unset($updates['q']); $response = false; $response = Post::where('id', '=', $id)->update($updates); if ($response === 1) $response = true; return response()->json($response); } /** * Remove the specified resource from storage. * * @param int $id * @return Response */ public function destroy($id) { $response = false; $response = Post::destroy($id); if ($response === 1) $response = true; return response()->json($response); } }
エラー処理などは何もしてないけど、これで一通り完成!
参考
関連記事
スポンサーリンク