アルバイトエンジニアの妹尾です。
今年の8月にLaravel5.3がリリースしましたね。
色々な変更がありましたが、個人的にはルーティングのファイルが別れたこともなかなか嬉しかったです。
大規模なプロジェクトになるとエンドポイントがたくさん増えてroute.phpがどんどん大きくなってしまいました。またRailsであってもroutes.rbが大きくなってしまっていました。
今回開発中の弊社の新サービスのLaravelのバージョンを5.3にあげたのでLaravelでの入門的なAPIの書き方について書こうと思います。
ルーティングの設定
まず、app/Providers/RouteServiceProvider.phpへルーティングファイルを登録します。
class RouteServiceProvider extends ServiceProvider
{
protected $namespace = 'App\Http\Controllers';
public function boot()
{
//
parent::boot();
}
public function map()
{
$this->mapWebRoutes();
$this->mapApiRoutes();
}
protected function mapWebRoutes()
{
// 普通のルーティング
}
protected function mapApiRoutes()
{
Route::group([
// Kernel.phpでapiに登録されているミドルウェアを適応
'middleware' => 'api',
// Controllers/Api以下にあるクラスに限定する
'namespace' => "{$this->namespace}\Api",
// エンドポイントを/api/somethingの形にする
'prefix' => 'api',
], function ($router) {
// api.phpを登録する
require base_path('routes/api.php');
});
}
}
これでroutes/api.phpへルーティングを書くことができるようになりました。
コントローラを書く
Laravelには様々な機能があり、コントローラを書く上ではValidatorが特に重宝していると思います。
試しに"/api/test?id=1&date=2016-09-28&title=MatchinGood"という感じでアクセスできるAPIのコントローラを描いてみます。
namespace App\Http\Controllers\Api;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class TestController extends Controller
{
public function test(Request $request)
{
$validator = Validator::make($request->all(), [
// 必須パラメータかつ整数
'id' => 'required|integer',
// 必須パラメータかつY-m-dの形
'date' => 'required|date_format:"Y-m-d"',
// 必須パラメータかつ文字列
'title' => 'required|string'
]);
if ($validator->fails()) {
return response()->json($validator->errors(), 422);
}
return response()->json(['status' => 'successful']);
}
}
こんな感じでどうでしょうか。煩雑になりがちなパラメータのバリデーションはすべてLaravelのValidatorに任せられます。公式ドキュメントには色々なバリデーションの種類がありますので適切なものを選択します。
APIなのでバリデーションが失敗した時の返り値もjsonである必要がありますが、$validator->errors()を使うとエラーの内容が取得できるのでそれを使うと楽できます。
ルーティング
コントローラがかけたのでいよいよapi.phpを書きます。
<?php
Route::get('test', 'TestController@test');
RouteServiceProviderでnamespaceをApp\Http\Controllers\Apiで設定してあるのでnamespaceの先頭のApiは省くことができます。
おまけ
実はLaravelには$request->wantsJson()でリクエストヘッダーに"ContentType: application/json"がセットされているかどうか調べることができます。なので単純にcompanyというリソースの詳細画面に行くURIが"/company/1"で、わざわざ別のコントローラにAPIを書きたくないと思った時は
public function show(Company $company, Request $request)
{
if ($request->wantsJson()) {
return $company;
}
return view('company.detail')->with('company', $company);
}
というふうにすることでリクエストのヘッダーに応じてjsonで返すことができます。
ここで、なぜ単純にEloquentのモデルをコントローラの返り値として返しているかというと、LaravelのEloquentのソースでは、
abstract class Model implements ArrayAccess, Arrayable, Jsonable, JsonSerializable, QueueableEntity, UrlRoutable
{
.
.
.
public function __toString()
{
return $this->toJson();
}
}
となっていて、stringにキャストする際にtoJson()を呼んでいることがわかります。toJson()ではモデルの各カラムの値とリレーションをjsonの文字列にして返します。なのでこれでモデルをそのままjsonの形式で返すことができています。
より詳しい実装がきになる方は実際にソースコードを読むことをお勧めします。
まとめ
いつもは入門みたいな感じの記事は書いていないのですが、今回は試しに入門記事のようなものを描いてみました。
フレームワークを簡単に触る分には日本語の記事がたくさんあるので誰でも使えると思うのですが、もっと深い部分を見ようと思うとLaravel自体のコードを見る必要があったり、今回のLaravelのアップデート内容をいち早く知りたければ英語の記事を読む必要があります。
プログラミング初心者の方には少しハードルが高く聞こえるかもしれませんが、やる気があればできます。弊社は少人数で開発していますが、今回の記事のような入門レベルから、まだ日本語の記事がないような最新のものにも触れる機会があります。
弊社はプログラミング初心者から実力者まで力を発揮することができる職場です。
ぜひ一度お話を聞きに来ませんか!?
マッチングッド株式会社では一緒に働く仲間を募集しています