Flask
Python3
Vue.js
vue-cli

Vue.js(vue-cli)とFlaskを使って簡易アプリを作成する【後半 - サーバーサイド編】

vueflask.png

どうもmiyachi(@_38ch)です。

前回の記事

Vue.js(vue-cli)とFlaskを使って簡易アプリを作成する【前半 - フロントエンド編】

で、フロントエンドVue.js、サーバーサイドFlaskで作る簡易SPAのフロントエンドの紹介をしました。

今回はサーバーサイド(Flask側)の作り方を書いていきます。

なお、サーバーサイドにはPython3.6を使っています。


backendディレクトリを作成

ディレクトリを切って、virtualenvで仮想環境を作ります。

$ mkdir backend

$ cd backend
$ virtualenv -p python3 venv

アクティベートします。

$ source venv/bin/activate

アクティベートが完了したら、Flaskをインストールします。

(venv) pip install Flask

ルートディレクトリ(frontend, backendと同じディレクトリ)に戻って、run.pyを作成。

(venv) cd ..

(venv) touch run.py

中身はこんな感じ

from flask import Flask, render_template

app = Flask(__name__,
static_folder = "./dist/static",
template_folder = "./dist")
@app.route('/')
def index():
return render_template("index.html")

このrun.pyは一般的なFlask starterとは少し異なります。

どこが違うかというと、static_folderとtemplate_folderの部分。

templateファイルはfrontendから生成されたものを読み込む必要があるので、ここでパスを指定しています。


Flaskサーバーを起動

以下を実行してあげると、Flaskサーバーが立ち上がります。

(venv) FLASK_APP=run.py FLASK_DEBUG=1 flask run

localhost:5000で確認できます。

最初のページはうまく表示されますが、/aboutに行くとNOT FOUNDになってしまいました。

image.png

run.pyの設定を少し変えてあげましょう。

@app.route('/', defaults={'path': ''})

@app.route('/<path:path>')
def catch_all(path):
return render_template("index.html")

これで正常にaboutページが表示されるはず。


APIエンドポイントを追加

1-100でランダムな数値を返すシンプルなAPIを作成します。

run.pyを以下のように修正します。

from flask import Flask, render_template, jsonify

from random import *
app = Flask(__name__,
static_folder = "./dist/static",
template_folder = "./dist")

@app.route('/api/random')
def random_number():
response = {
'randomNumber': randint(1, 100)
}
return jsonify(response)

@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')
def catch_all(path):
return render_template("index.html")

'/api/random'にリクエストを投げるとランダムな数値を以下のようなJSON形式で返してくれる。

{

"randomNumber": 36
}

ブラウザで localhost:5000/api/random にアクセスしてテストできます。

image.png

サーバーサイドで動作が確認できたら、それをフロントから呼べるようにしましょう。

Home.vueを以下のように修正します。


Home.vue

<template>

<div>
<p>Home page</p>
<p>Random number from backend: {{ randomNumber }}</p>
<button @click="getRandom">New random number</button>
</div>
</template>

<script>
import axios from 'axios'

export default {
data () {
return {
randomNumber: 0
}
},
methods: {
getRandom () {
this.randomNumber = this.getRandomFromBackend()
},
getRandomFromBackend () {
const path = `http://localhost:5000/api/random`
axios.get(path)
.then(response => {
this.randomNumber = response.data.randomNumber
})
.catch(error => {
console.log(error)
})
}
},
created () {
this.getRandom()
}
}
</script>


大まかに説明すると、


  • randomNumberは0で初期化されている。

  • ボタンをクリックすると、getRandomが走る。

  • getRandomが走ると、サーバーサイドにHTTPリクエストが送られ、ランダムな数値が返ってくる。

  • randomNumberが更新されて、画面の値が変わる

という感じです。

backendにHTTPリクエストをなげるためには、axiosというライブラリを使用します。

(venv) cd frontend

(venv) npm install --save axios

フロントを更新したので、再度 npm run build を実行して、

localhost:5000から確認します。

Jun-03-2018 1-02-26 PM.gif

正常にランダムな数値を取得するAPIを実装できました。

間違え、ご指摘などあれば、コメント欄にいただけると助かります。


ソースコード

今回使用したコードはこちらにあげておきます。

もしお役にたったらStarいただけると嬉しいです。

https://github.com/miyachin/vue-flask-sample