VueとRailsで何をするか
前回バックエンドにRruby on Rails、フロントエンドにVue.jsとVuetifyを使ったDocker環境を構築しました。今回はRuby on Railsコンテナの中にAPIを用意してVue側からそれを叩き、シェルスクリプトを実行してみたいと思います。
これが実現すればブラウザからシェルスクリプトを実行出来る事になります。UIを選択式にすることでかなりの時短になる上に、机にいなくてもスマホを使って何処からでもシェルスクリプトを実行可能になります。
vue-routerを追加
Vue側の実装から取り掛かっていきます。まずはタブメニューから表示するコンテンツを切り替えるためのルーティングを実装したいので、vue-routerを導入します。いかのコマンドを実行してパッケージをインストールします。
$ npm install vue-router
front/src/main.js
に下記を記述します。
import Vue from 'vue'
import App from './App.vue'
import vuetify from '@/plugins/vuetify';
import router from './router'
Vue.config.productionTip = false
new Vue({
vuetify,
router,
render: h => h(App)
}).$mount('#app')
front/src/router.js
に下記を記述します。
import Vue from 'vue'
import Router from 'vue-router'
import Shell from './components/Shell.vue'
import Rabbit from './components/Rabbit.vue'
Vue.use(Router)
export default new Router({
mode: 'history',
routes: [
{
path: '/shell',
name: 'shell',
component: Shell
},
{
path: '/rabbit',
name: 'rabbit',
component: Rabbit
}
]
})
これでルーティングの設定は完了です。
App.vueを作成
次は今回のVueプロジェクトのトップページとなるApp.vueを試作します。とても適当です。
<template>
<div
class="main"
>
<v-tabs
fixed-tabs
background-color="indigo"
>
<v-tab to="/shell">
Shell
</v-tab>
<v-tab to="/rabbit">
Rabbit
</v-tab>
<v-tab>
Other
</v-tab>
<v-tab>
Settings
</v-tab>
<v-tab>
About
</v-tab>
</v-tabs>
<v-main>
<router-view></router-view>
</v-main>
</div>
</template>
<script>
export default {
name: 'App',
data: () => ({
//
}),
};
</script>
<style>
.main {
padding: 20px;
}
</style>
Vueコンポーネント作成
Shell.vueコンポーネントを試作
次にfront/src/components/Shell.vue
とfront/src/components/Rabbit.vue
の各コンポーネントを作成します。Shell.vueはバックエンドのRails APIを叩くためのフォームを作成しています。
<template>
<v-form>
<v-row
class="arg-row"
>
<v-col
cols="6"
md="2"
>
<v-text-field
v-model="argument1"
label="引数1"
/>
</v-col>
<v-col
cols="6"
md="2"
>
<v-text-field
v-model="argument2"
label="引数2"
/>
</v-col>
</v-row>
<v-btn
color="primary"
dark
@click="excecuteShellScript"
>
EXECUTE
</v-btn>
</v-form>
</template>
<script>
export default {
data: function () {
return {
argument1: null,
argument2: null
}
},
methods: {
excecuteShellScript: function () {
console.log(this.argument1, this.argument2)
}
}
}
</script>
<style>
.arg-row {
margin: 0 auto;
}
</style>
Rabbit.vueの方は中身は適当で大丈夫です。ここでは使用しないのですがVuetifyのデバッグがしたかったのと今後作りたいものがあったのでファイルだけ用意しただけです。
「EXECUTE」ボタンを押してコンソールにフォームで入力した値が出力されていればShell.vueコンポーネントの作成は一旦成功です。まだ終わりじゃありませんが。
Rails APIの作成
ルーティング
Shell.vueからの非同期リクエストをコントローラにルーティングするためapi/config/routes.rb
に下記を記述します。
Rails.application.routes.draw do
namespace :api, format: 'json' do
scope module: :script do
resource :shell_script, only: %i[update], param: :message
end
end
end
コントローラ作成
次に先程のルーティング先となるコントローラを作成します。api/app/controllers/api/script/shell_scripts_controller.rb
に下記を記述して下さい。
module Api
module Script
class ShellScriptsController < ActionController::API
def update
p params['arguments']['argument1']
end
end
end
end
Shell.vueを改修
Vue.jsにaxiosを導入して非同期処理
続いてShell.vueから先程作成したRails APIを叩くために非同期でHTTPリクエストを送る処理を実装します。そのためにaxiosというライブラリをVueプロジェクトにインストールします。
$ npm install --save axios
Shell.vueも改修します。
※URLのホスト名に関しては各々の環境に合わせてください。
<script>
import axios from 'axios'
export default {
data: function () {
return {
argument1: null,
argument2: null
}
},
methods: {
excecuteShellScript: function () {
const query = {
arguments: {
argument1: this.argument1,
argument2: this.argument2
}
}
axios.patch('http://【ローカルホストのIPアドレス】:3001/api/shell_script', query)
.then((response) => {
console.log(response);
})
.catch((error) => {
console.log(error)
})
}
}
}
</script>
APIの動作確認
ここで「EXECUTE」ボタンを押してみてHTTPリクエストを飛ばせているか、またAPIが動作しているかを確認してみて下さい。下記のコマンドでRailsコンテナのログを出力してみてarguments
の値を受け取れていれば成功です。
$ docker logs 【Ruby on Railsのコンテナ名】 -f
APIが実行する用のシェルスクリプト作成
現状ログに出力するだけの処理でしたが次はシェルスクリプトを実行させてみましょう。そのためにshell_scripts_controller.rb
コントローラに実行させるシェルスクリプトを作成します。api/lib/scripts/date.sh
に下記を記述して下さい。
#!/bin/bash
cd /app/lib/scripts
echo `date` > ./hoge
shell_scripts_controller.rb
を下記の様に書き直して下さい。
module Api
module Script
class ImageScraypingsController < ActionController::API
def update
p params['arguments']['argument1']
system('bash ./lib/scripts/date.sh')
end
end
end
end
これで全ての準備が完了しました。「EXECUTE」ボタンを押してみて下さい。Shell.vueから非同期でRails APIにリクエストが送られ、ShellScriptsControolerがそれを受けてdate.shを実行します。するとhogeファイルが作成されて時刻が書き換えられている筈です。VueからAPIを叩くという目標が達成出来ました。
終わりに
今回はVueでRailsのAPIを叩いてみましたが、この非同期でAPIを叩くという行為は非常に重要な概念です。必要な分だけ通信が発生するので大変無駄がありません。昨今のSPAの多くが似た様な実装をしています。
テストを書いたり、VuetifyでUIを改善したり、バックエンドでより複雑な処理を実装してみたりとやるべきことはまだまだたくさん残っているので、そちらも挑戦してみたいと思います。