4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【旧版】ExcelからElixirマスター⑥:Vue.js+内部API (表示編)

Last updated at Posted at 2023-01-01

【本コラムは、5分で読めて、15分くらいでお試しいただけます】
piacereです、ご覧いただいてありがとございます :bow:

前回までは、シンプルなPhoenixのサーバサイドレンダリング(SSR)により、Web上にDBデータや外部APIデータを表示してきました

今回からは、Vue.jsを使ったフロントサイドと、Phoenixによる内部APIを組み合わせを用いて、よりElixir/Phoenixらしさを実感できるWeb開発へとステージアップします

■「ExcelからElixirマスター」シリーズの目次
①データ並替え/絞り込み
|> ②データ列抽出、Web表示
|> ③WebにDBデータ表示
|> ④Webに外部APIデータ表示
|> ⑤Webにグラフ表示
|> ⑥Vue.js+内部API(表示編)
|> ⑦Vue.js+内部API(更新編)
|> ⑧Gigalixirに本番リリース
|> ⑨Elixir/PhoenixのCRUD Webアプリをリリース
|> ⑩「LiveView」ElixirサーバサイドのみでReact的SPA/リアルタイムUIが作れる
|> ⑪LiveView製Qiita検索SPAをフォームsubmitスタイルに換装
|> ⑫LiveViewのコード内HTMLをテンプレートファイルに分離
|> ⑬ElixirサーバサイドSPAをスマホで見るためにGigalixirリリース
|> ⑭Gigalixir上のLiveViewアプリに独自ドメイン名を付与して正式なアプリ公開


:stars::stars::stars: お知らせ:Elixir MeetUpを来週末10/26(金)に開催します(リモート視聴も) :stars::stars::stars:

「fukuoka.ex#16:蔵出し始めました!Elixir実践テクニック公開します① 」を10/26(金)19時に開催します

今回のMeetUpから、「座談会+モブプログラミング」という形で、fukuoka.exアドバイザーズ/キャストが、過去会で登壇したり、日頃研鑽している数々のElixir実践テクニックをダイレクトに伝えていきます

今回は、「Elixir+Vue.jsで2倍速開発」と「ElixirでElixirコンパイラ開発」の2トラックにて、集まった皆さまと一緒にElixir実践テクニックをシェアしたいと思います

https://fukuokaex.connpass.com/event/105154
image.png

一応、リモート視聴にも対応していますが、福岡近辺にお住まいの方であれば、遊びに来ていただいて、参加型コンテンツを120%楽しんでいただくのが絶対オススメです

DBのインストール

フロントサイドで表示したり、投入するデータをDBに入れるため、まずDBサーバをインストールします

ここでは、DBサーバとして、「PostgreSQL」か「MySQL」のいずれかをインストールすることとします

image.png

パスワードは、PostgreSQLは「postgres」、MySQLは未設定(空文字列)で設定しておくと、Phoenix PJ作成後に設定変更が不要になります

※下記リンク先コラムの中には、「パスワードの weak 評価はダメ」といった記載ありますが、本番環境の構築をしている訳では無いので構いません

①PostgreSQLのインストール

image.png

下記OS毎のインストール手順を実施してください

Windows:https://eng-entrance.com/postgresql-download-install
macOS:https://qiita.com/okame_qiita/items/ac7b6a7d96d07ecbc50b
Ubuntu:https://qiita.com/eighty8/items/82063beab09ab9e41692
CentOS 7:https://weblabo.oscasierra.net/postgresql10-centos7-install/
CentOS 6:https://weblabo.oscasierra.net/postgresql-installing-postgresql9-centos6-1/

なおUbuntuの場合、インストール直後のpostgresユーザのパスワードを下記SQLで設定し、PostgreSQLを再起動する必要があります

ALTER USER postgres WITH PASSWORD 'postgres';

②MySQLのインストール

image.png

下記OS毎のインストール手順を実施してください

Windows:https://qiita.com/KeisyaRinco/items/c3074d8450cad96f7e4f
macOS:https://qiita.com/griffin3104/items/c7908359a3e3e18cd269
Ubuntu:https://www.server-world.info/query?os=Ubuntu_16.04&p=mysql
CentOS 7:https://enomotodev.hatenablog.com/entry/2016/09/01/225200
CentOS 6:https://qiita.com/UmedaTakefumi/items/924cdce7cfff083bf492

Vue.js向け内部API用Phoenix PJを作成

Phoenix PJを作成します

mix phx.new vue_sample
Fetch and install dependencies? [Yn] (←y、Enterを入力)
…
cd vue_sample

あと、PostgreSQLの場合は、DB指定不要ですが、MySQLの場合は、DB指定が必要です

※MySQLの場合
mix phx.new vue_sample --database=mysql
Fetch and install dependencies? [Yn] (←n、Enterを入力)
…

パスワードを、以下以外で設定している場合は、config/dev.exsの「password」項目の修正が必要です

  • PostgreSQL:postgres
  • MySQL:未設定(空文字列)
config/dev.exs ※MySQLの場合

# Configure your database
config :vue_sample, VueSample.Repo,
  username: "root",
  password: "",
  hostname: "localhost",
  database: "vue_sample_dev",
  show_sensitive_data_on_connection_error: true,
  pool_size: 10

ちなみにPostgreSQLだと、以下に相当します

config/dev.exs ※PostgreSQLの場合

# Configure your database
config :vue_sample, VueSample.Repo,
  username: "postgres",
  password: "postgres",
  hostname: "localhost",
  database: "vue_sample_dev",
  show_sensitive_data_on_connection_error: true,
  pool_size: 10

DBを作成します

mix ecto.create

Phoenixサーバーを起動します

iex -S mix phx.server

ブラウザで「http://localhost:4000」にアクセスすると、Phoenixで作られたWebページが見れます
image.png

PhoenixでAPIを作る

PhoenixでAPIを作るには、mixコマンドで、以下のように行います

Ctrl+cを2回押して、一度、Phoenixを停止してから、コマンドを入力します

mix phx.gen.json Api Post posts title:string body:text

以下ログと、実行後の作業指示が示されます

* creating lib/vue_sample_web/controllers/post_controller.ex
* creating lib/vue_sample_web/views/post_view.ex
* creating test/vue_sample_web/controllers/post_controller_test.exs
* creating lib/vue_sample_web/views/changeset_view.ex
* creating lib/vue_sample_web/controllers/fallback_controller.ex
* creating lib/vue_sample/api/post.ex
* creating priv/repo/migrations/20220201143346_create_posts.exs
* creating lib/vue_sample/api.ex
* injecting lib/vue_sample/api.ex
* creating test/vue_sample/api_test.exs
* injecting test/vue_sample/api_test.exs
* creating test/support/fixtures/api_fixtures.ex
* injecting test/support/fixtures/api_fixtures.ex

Add the resource to your :api scope in lib/vue_sample_web/router.ex:

    resources "/posts", PostController, except: [:new, :edit]


Remember to update your repository by running migrations:

    $ mix ecto.migrate

まず、ルーティングにAPI用エントリーとして、上記「resources "/posts", ~」を、「get "/", ~」直下に追記します

lib/vue_sample_web/router.ex
defmodule VueSampleWeb.Router do
  use VueSampleWeb, :router
  
  scope "/", VueSampleWeb do
    pipe_through :browser

    get "/", PageController, :index
    resources "/posts", PostController, except: [:new, :edit]
  end
  

マイグレートします

mix ecto.migrate

以下ログのように、テーブルが作成されます

01:51:55.226 [debug] Selecting all records by match specification `[{{:schema_migrations, :"$1", :"$2"}, [], [[:"$1"]]}]` with limit nil

01:51:55.282 [info]  == Running VueSample.Repo.Migrations.CreatePosts.change/0 forward

01:51:55.282 [info]  create table posts

01:51:55.310 [info]  == Migrated in 0.0s

Phoenixを起動してください

iex -S mix phx.server

APIでデータを参照する

先ほど作成したAPIで、データを参照してみましょう(と言っても、未だデータ投入していないので、空が返ってくるだけですが…)

APIを叩くために、REST APIクライアントが必要ですが、Firefoxの「RESTClient」、Chromeの「Postman」が便利です

Firefox「RESTClient」
https://addons.mozilla.org/ja/firefox/addon/restclient/

Chrome「Postman」
https://chrome.google.com/webstore/detail/postman/fhbjgbiflinjbdggehcddcbncdddomop

ここでは、FirefoxのRESTClientをインストールして、使ってみます

まず、RESTClientの「Headers」メニューで、「Custom Header」を選択して、REST API用のヘッダー設定をします
image.png

次に、URLに「http://localhost:4000/posts」を入れ、「SEND」ボタンをクリックすると、以下のような画面になります
image.png

「Headers」タブから、「Response」タブに切り替えると、中身が空のデータが返っていることが確認できます
image.png

APIでデータを投入する

では、APIでデータ投入してみましょう

「Method」を「POST」に変更し、「Body」に以下を入力します

{ "post": { "title": "t1", "body": "b1" } }

「SEND」ボタンをクリックすると、以下の通り、エラーになります
image.png

「Response」の中身を見てみると、CSRFトークンエラーが出ています

これは、リクエストにCSRFトークンが付与されていないことが原因ですが、ステートレスなAPIでCSRF対応は、このコラムの本筋から大きく外れるので、いったんシンプルにrouter.exに設定されているCSRF対策を解除します

lib/vue_sample_web/router.ex
defmodule VueSampleWeb.Router do
  use VueSampleWeb, :router

  pipeline :browser do
    plug :accepts, ["html"]
    plug :fetch_session
    plug :fetch_flash
#   plug :protect_from_forgery
    plug :put_secure_browser_headers
  end
  

コンパイルします

iex> recompile

再度、「SEND」ボタンをクリックすると、今度は成功します
image.png

「Method」を「GET」に切り替え、「SEND」ボタンをクリックすると、投入したデータが返っていることが確認できます
image.png

もう1件、データ投入しておきましょう

「Method」を「POST」に変更し、「Body」に以下を入力し、「SEND」ボタンをクリックします

{ "post": { "title": "t2", "body": "b2" } }

Vue.jsでデータ表示する(axiosでAPI呼出)

Vue.jsとaxiosを使って、上記で作成したAPIの呼び出しを行い、テーブル表示してみます

Vue.jsとaxiosは、「<script src=~」でCDN(Content Delivery Network)を指定することでロードします

「var app = new Vue」で始まるブロックが、Vue.jsのメイン処理です

メイン処理の「el」で指定したものと同じidを、上方のdivタグで指定していますが、Vue.jsはこの中で有効です

trタグに指定した「v-for」では、メイン処理の「data」で定義しているresults配列を1件ずつ取り出し、resultに代入しており、各フィールドを「{{ result.【フィールド名】 }}」という記述で取得できます

なお、results配列は、初期表示時に実行される「mounted」ハンドラ内の、axiosによるAPI呼出で更新されます

lib/vue_sample_web/templates/page/index.html.heex
<section class="phx-hero">
  <h1><%= gettext "Welcome to %{name}!", name: "Phoenix" %></h1>
  <p>Peace of mind from prototype to production</p>
</section>

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>

<div id="app">

<h1>Posts</h1>
<table border="1">
<tr v-for="result in results">
	<td style="padding: 10px;">{{ result.title }}</td>
	<td style="padding: 10px;">{{ result.body }}</td>
</tr>
</table>

</div>

<script>
	var app = new Vue
	( {
		el: '#app',
		data: 
		{
			results: [], 
		}, 
		mounted()
		{
			axios.get( '/posts' )
			.then( response => { this.results = response.data.data } )
		}, 
	} )
</script>

APIで取得できるデータがテーブル表示されます
image.png

RESTClientから、もう1件、データ投入します

{ "post": { "title": "t3", "body": "b3" } }

ブラウザをリロードすると、増やしたデータが表示されます
image.png

終わり

今回は、Vue.jsを使ったフロントサイドと、Phoenixによる内部APIを組み合わせを用いて、APIにより取得したデータを画面表示してみました

次回は、画面入力と、APIによるデータ更新 を行ってみます

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?