Laravel でリソースをフレキシブルに生成するパッケージ「FlexibleResource」を公開しました!

さてさて、このブログでもよく紹介しているのですが、Laravelが多機能で高機能なのは多くの開発者が認めるところでしょう。

ただ、全てを全自動でやってくれるかと言えば、もちろんそんな訳はなく、やはりそこは自前で開発する必要がでてきます。

とはいってもそこは人気フレームワークのLaravel
もし何か欲しい機能があったら独自に改造しやすくしてくれています。例えばユーザー情報もマイグレーション内ですぐ新しいフィールドを追加できますし、モデルのaccessorなんかもとてもフレキシブルにデータ加工ができます。

そして、今回開発の中でひとつ課題になったのがResource APIです。
Laravelにはこの情報を生成する機能はついていますが、通常Ajaxを通してアクセスするためには用意したURLに1つずつアクセスしないといけません。例えば、5つのデータが必要なら5アクセスです。

これでは、あまり負荷的にもレスポンス的にもよくはないかもしれません。

そこで、1アクセスするだけですでに準備しておいたリソースを可変的に取得することができる独自パッケージ「FlexibleResource」を作成し、公開しました。

今回はその使い方を紹介します!

※ 開発環境: Laravel 5.7

FlexibleResourceができること

一気にリソース情報を取得できる

例えば、次のようにkeysにパラメータをつけることで一気に必要なデータを取得することができるようになります。

https://example.com/resource?keys=userTypes|userNames

取得データはこのようにJSONでキーごとに用意されるようになります。

{
"userTypes":{"1":"admin","2":"owner","3":"user"},
"userNames":{"1":"name1","2":"name2","3":"name3"}
}

各データにパラメータを追加できる

例えば、次のように個別にパラメータをつけることができます。(使い方はあとで詳しく紹介します)

https://example.com/resource?keys=userTypes:value_1,value_2,value_3

※ ちなみにパラメータの付け方はLaravelのバリデーション・ルールと同じです。

自動でコレクション(配列)化できる

JavaScriptでは、オブジェクトの順番が保証されていないため、しばしば配列に変換してデータの送受信をします。これを自動的に行うことができます。

例えば、userTypesからデータ取得ができる場合、userTypeCollectionとすると次のようにkeyvalueのコレクションになって返ってきます。(つまり、わざわざuserTypeCollection()のコードを書く必要はありません)

{
"userTypeCollection":[
{"key":1, "value":"admin"},
{"key":2, "value":"owner"},
{"key":3, "value":"user"}
]
}

また、keyvalueを変更することもできます。
その場合は$auto_collectionsへ指定してください。

class ResourceController extends Controller
{
use FlexibleResourceTrait;

protected $auto_collections = [
'userTypes' => ['id' => 'type']
];

すると、データは次のようになります。

{
"userTypeCollection":[
{"id":1, "type":"admin"},
{"id":2, "type":"owner"},
{"id":3, "type":"user"}
]
}

インストール

他のパッケージと同じくcomposerで一気にインストールできます。

composer require sukohi/flexible-resource:1.*

※ Laravel 5.7でメンテナンスしてますがTraitを使っているだけなので、おそらく過去バージョンでも動くと思います。

準備

次のようにFlexibleResourceTraitをコントローラーから呼び出すだけでOKです。

class ResourceController extends Controller
{
use FlexibleResourceTrait;

なお、ルーティングは次のようになります。

Route::get('resource', 'ResourceController@get');

個別データの設定

トレイトとルーティングを準備したら、各個別データの設定です。
データの設定はprivateメソッドで行います。

例えば、先ほどのuserTypesの例で言うとこうなります。

class ResourceController extends Controller
{
// 省略

private function userTypes() {

return [
1 => 'admin',
2 => 'owner',
3 => 'user'
];

}

※ なお、返す値はLaravelCollectionでも問題ありません。

そして、パラメータを付けた場合は通常通り引数を利用することができます。
データの並べ替えや絞り込みに使うといいでしょう。

private function userTypes($direction = 'asc') {

$user_types = [
1 => 'admin',
2 => 'owner',
3 => 'user'
];

if($direction == 'desc') {

return collect($user_types)->reverse();

}

return $user_types;

}

Vue.jsと連携して使う

もしVue.jsからFlexibleResourceで生成したデータを取得したい場合は、専用Vueミックスイン「v-flexible-resource」も公開しているのでこちらを利用してください。(要axios)

インストール

npm でインストールできます。

npm i v-flexible-resource --save

使い方

resourceMixinという変数にミックスインが格納されているので、resource.jsを読み込んで次のように使ってください。

<script src="/PATH/TO/YOUR/FOLDER/v-flexible-resource/resource.js"></script>
<script>

new Vue({
el: '#app',
data: {
userTypes: {},
userTypeCollection: []
},
mounted() {

var keys = ['userTypes', 'userTypeCollection'];
this.resource(keys, function(data){

console.log(data); // コールバック関数は省略可

});

}
})

</script>

なお、data変数への格納はミックスイン内で自動的に行われますので、コールバック関数は省略することができます。

また、リソースのURLを変更したい場合は、resourceUrlを上書きしてください。

data: {
resourceUrl: '/YOUR/RESOURCE/URL'
},

【追記: 2018.12.19】 パッケージ内でVue.mixin()を自動的に実行するようにしましたので、resourceMixinという変数は必要なくなりました。

おわりに

ということで、今回はResource APIをフレキシブルに使うことができる独自パッケージを紹介しました。

ちなみに、当初はLaravel側のパッケージ内にVueのコードも格納するつもりでしたが、Laravel Mixで使うにはnpmパッケージにするべきとの判断からパッケージは分割することになりました。

このパッケージが役にたてたら嬉しいです。

ではでは〜!