Laravel5.5こと始め 〜7. Vue.jsとAPIベースのユーザ管理アプリの追加準備〜


内容

以下の順番にまとめます。
1. MacへのXAMPP+Laravelインストール
2. ユーザログイン機能の追加
3. MVCとルーティングの説明
4. ユーザリストの表示
5. ユーザリストのペジネーション表示
6. ユーザ管理APIの追加
7. Vue.jsとAPIベースのユーザ管理アプリの追加準備 ←いまここ
8. Vue.jsとAPIベースのユーザ管理アプリの追加
9. Vue.jsとAPIベースのユーザ管理アプリへのペジネーション追加
10. APIへのJWTAuth認証の追加
11. Vue.jsとAPIベースのユーザ管理アプリへの認証の追加

7. Vue.jsとAPIベースのユーザ管理アプリの追加準備

LaravelはVue.jsとよばれるJavaScriptベースのシングル・ページ・アプリケーション(SPA)構築フレームワークと相性がよいです。

SPAアプリでは、従来のサーブレットWebアプリケーションのようにWebサーバが動的にHTMLを生成して、セッションに紐付いて画面遷移をしていくようなしくみではなく、サーバとのやりとりはRestAPIで行い、一括ダウンロードされるJavaScriptが画面遷移も制御するしくみをとります。これにより、ブラウザベースのアプリケーションであってもネイティブなスマートフォンアプリケーションに近いUIの実現が可能になります。

昨今ではJavaScriptのレンダリングのスピードも高速化しているため、これらのWebPackのしくみは、CordovaベースのIonicMonacaのようにハイブリッド・アプリケーションのベース技術として利用され始めています。

ハイブリッド・アプリケーションでは、HTML5やCSS、JSといったオンラインのWebアプリケーション技術をスマートフォンのネイティブアプリに同梱して、Webアプリを開発する要領でネイティブのスマホアプリを開発します。これにより、構築したアプリがレスポンシブ対応を施していれば、ブラウザが異なってもUIを統一化することができるため、ネイティブアプリケーションを構築する場合、iPhoneではSWIFTやObjective-C、AndroidではJava on Eclipse、PCではPHPでWebアプリを開発する、といった同一の目的にもかかわらずプラットフォームごとに異なるアプリを開発しなければならないという問題を解決することができます。

さらに最近ではProgressive Web Apps (PWA)のしくみを使えば、Apple StoreやGoogle Playにリリースされたネイティブ・アプリケーションをインストールしなくても、スマートフォンアプリにアイコンを追加することが可能になり、データキャッシュのしくみを使ってオフライン対応も可能になっています。これにより、さらに手軽に、効率的に、使い勝手がよいハイブリッド型のアプリケーションの提供が可能になってきています。

以上、うんちくをつらつらと申し上げましたが、ここではLaravelをうまく使ったVue.jsとRestAPIの連携の方法を解説していきます。

7.1 nodejsのライブラリを管理するnpmコマンドのインストール

homebrewでnpmをインストールします。

$ brew install npm

7.2 Vue.js関連のライブラリのインストール

nodejsライブラリとして、「ajv」、「vue-router」、「vuetable-2」、「vue-axios」を追加でインストールします。

$ npm install --save-dev ajv vue-router vuetable-2 vue-axios
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN [email protected] requires a peer of vue@>= 1.0.0 but none is installed. You must install peer dependencies yourself.

+ [email protected]
+ [email protected]
+ [email protected]
+ [email protected]
added 13 packages from 14 contributors and audited 13 packages in 3.513s
found 0 vulnerabilities

このコマンドを実行すると、プロジェクトフォルダ配下にpackage.jsonファイルが下記の通り編集されます。

package.json
{
    "private": true,
    "scripts": {
... (中略)
    },
    "devDependencies": {
        "ajv": "^6.5.2",
        "axios": "^0.18",
        "bootstrap": "^4.0.0",
        "cross-env": "^5.1",
        "jquery": "^3.2",
        "laravel-mix": "^2.0",
        "lodash": "^4.17.4",
        "popper.js": "^1.12",
        "vue": "^2.5.7",
        "vue-axios": "^2.1.2",
        "vue-router": "^3.0.1",
        "vuetable-2": "^1.7.5"
    }
}

さらに「npm install」コマンドを実行します。

$ npm install

> [email protected] install /Users/Retina/userauth/node_modules/fsevents
> node install
... (中略)
  ✔ pngquant pre-build test passed successfully
added 1560 packages from 760 contributors and audited 19040 packages in 31.552s
found 17 moderate severity vulnerabilities
  run `npm audit fix` to fix them, or `npm audit` for details

「found 17 moderate severity vulnerabilities」というのは、npmがインストールしたライブラリのセキュリティ脆弱性をリストくれる機能です。「npm audit」を実行するとライブラリの依存関係とどのような脆弱性があるか教えてくれます。ここでは、とりあえず無視して開発を進めます。

7.3 ルーティングの設定

Laravelでは新たにページを追加する場合、URIと画面遷移を考えるとよいです。今回は、Vue.jsでSPA画面を一つ用意するだけですので、例えば、http://localhost:8000/home2 というURIで画面が表示されるViewとControllerを考えます。ただし、今回は画面に渡されるデータはRestAPIで取得しますので、コントローラは作成せず、ルーティングの設定のみですませることができます。

Viewのコードは以下の通りです。「<router-view/>」のタグはVue.jsのコンポーネントを表します。Vue.jsのコンポーネントやルーティングについてはあとでまとめて説明します。

resources/views/home2.blade.php
@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <div class="panel panel-default">
                <div class="panel-body">
                    <router-view/>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

ルーティングの設定は以下の通りです。

routes/web.php
<?php

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    return view('welcome');
});

Auth::routes();

Route::get('/home', 'HomeController@index')->name('home');

Route::middleware('auth')->get('/home2', function () {
    return view('home2');
})->name('home2');

「Route::middleware('auth')」は、このルーティングにauth認証をセットすることを意味します。auth認証をセットするというのは、ユーザログインが成功していなければ、ログインページに遷移することを表します。

それに続く「->get('/home2', function () {return view('home2');})」は、URI「/home2」へのHTTP GETメソッドが実行されたら、'home2'View つまり「resources/views/home2.blade.php」を表示することを表します。

最後の「->name('home2');」は、このルーティングの名前を'home2'と名付けることを示します。

以上、ルーティングがどう設定されているか見てみましょう。

$ php artisan route:list
+--------+-----------+------------------------+------------------+------------------------------------------------------------------------+------------+
| Domain | Method    | URI                    | Name             | Action                                                                 | Middleware |
+--------+-----------+------------------------+------------------+------------------------------------------------------------------------+------------+
|        | GET|HEAD  | /                      |                  | Closure                                                                | web        |
|        | GET|HEAD  | api/users              | users.index      | App\Http\Controllers\UserController@index                              | api        |
|        | POST      | api/users              | users.store      | App\Http\Controllers\UserController@store                              | api        |
|        | GET|HEAD  | api/users/create       | users.create     | App\Http\Controllers\UserController@create                             | api        |
|        | GET|HEAD  | api/users/{user}       | users.show       | App\Http\Controllers\UserController@show                               | api        |
|        | PUT|PATCH | api/users/{user}       | users.update     | App\Http\Controllers\UserController@update                             | api        |
|        | DELETE    | api/users/{user}       | users.destroy    | App\Http\Controllers\UserController@destroy                            | api        |
|        | GET|HEAD  | api/users/{user}/edit  | users.edit       | App\Http\Controllers\UserController@edit                               | api        |
|        | GET|HEAD  | home                   | home             | App\Http\Controllers\HomeController@index                              | web,auth   |
|        | GET|HEAD  | home2                  | home2            | Closure                                                                | web,auth   |
|        | POST      | login                  |                  | App\Http\Controllers\Auth\LoginController@login                        | web,guest  |
|        | GET|HEAD  | login                  | login            | App\Http\Controllers\Auth\LoginController@showLoginForm                | web,guest  |
|        | POST      | logout                 | logout           | App\Http\Controllers\Auth\LoginController@logout                       | web        |
|        | POST      | password/email         | password.email   | App\Http\Controllers\Auth\ForgotPasswordController@sendResetLinkEmail  | web,guest  |
|        | GET|HEAD  | password/reset         | password.request | App\Http\Controllers\Auth\ForgotPasswordController@showLinkRequestForm | web,guest  |
|        | POST      | password/reset         |                  | App\Http\Controllers\Auth\ResetPasswordController@reset                | web,guest  |
|        | GET|HEAD  | password/reset/{token} | password.reset   | App\Http\Controllers\Auth\ResetPasswordController@showResetForm        | web,guest  |
|        | GET|HEAD  | register               | register         | App\Http\Controllers\Auth\RegisterController@showRegistrationForm      | web,guest  |
|        | POST      | register               |                  | App\Http\Controllers\Auth\RegisterController@register                  | web,guest  |
+--------+-----------+------------------------+------------------+------------------------------------------------------------------------+------------+

URI列が「home2」の行が追加されたことを確認してください。Action列が「Closure」となっているのは、コントローラを指定せずルーティングを設定したためです。また、Middleware列が「web,auth」となっており、auth認証が設定されていることがわかります。

ここではたと気づくのですが、URI列が「home」の行のMiddleware列も「web,auth」となっています。「routes/web.php」では「Route::get('/home', 'HomeController@index')->name('home');」となっており、特にauth認証が指定されているわけではありません。これはどういうことかというとコントローラを見てみましょう。

app/Http/Controllers/HomeController.php
(中略)
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('auth');
    }
(中略)

上記のとおり、コンストラクターで「$this->middleware('auth');」とauth認証が指定されています。「php artisan route:list」コマンドはこの記述に反応して、Middleware列が「web,auth」となるわけです。

ここで「php artisan serve」を実行、http://localhost:8000/home2 にアクセスして、動作を確認してみましょう。

まずログイン画面が表示されます。

登録されたユーザでログインしすると下図のとおりコンテンツ部分になにもないページが表示されます。

「resources/views/home2.blade.php」の「<router-view name="usersIndex"></router-view>」タグ部分はまだ定義されていないためなにも表示されません。

以上、「7. Vue.jsとAPIベースのユーザ管理アプリの追加準備」が完了です。

次は、「8. Vue.jsとAPIベースのユーザ管理アプリの追加」です。