Help us understand the problem. What is going on with this article?

Excelから関数型言語マスター4回目:Webに外部APIデータ表示

(この記事は、「Elixir or Phoenix Advent Calendar 2017」の18日目です)

昨日は、@takasehideki さんの「ElixirでIoT#3:IoTボードで動いた!Phoenixが立った!性能評価と考察」でした


fukuoka.ex代表のpiacereです
今回もご覧いただいて、ありがとうございます:bow:

この連載の、前回までの記事は、以下になります

前回までは、fukuoka.ex#8で披露した、マーケティングに強いCTOが語る技術未来とElixir:第2回「プログラミング未経験でもExcelできればElixirマスターできる ~ITのパラダイムシフトで従来の知識・経験が邪魔になる時~」の範疇内でしたが、今回と次回は、このスライドに書かれていない領域について解説します

今回は、まず列名表示を修正した後、「列の抽出」を行い、その後、Web上に外部APIで取得したデータを表示します

データ内にある「列名」で列表示

前回、DBからデータ取得できるようになったのですが、取得したデータ内に「列名」があるので、それを使うと、各列を個別に指定しなくても列表示ができるようになります

columnsに、DBから取得した「列名」を設定し、各列の表示時に、forで出力するように変更します

lib/sample_db_web/templates/page/index.html.eex
<%
result = Db.query( "select * from members" )
data = result |> Db.columns_rows
columns = result |> Db.columns
%>
<table border="1">
<%= for record <- data do %>
<tr>
  <%= for column <- columns do %>
  <td><%= record[ column ] %></td>
  <% end %>
</tr>
<% end %>
</table>

ついでに、列名を表示する先頭行も追加します

lib/sample_db_web/templates/page/index.html.eex
<%
result = Db.query( "select * from members" )
data = result |> Db.columns_rows
columns = result |> Db.columns
%>
<table border="1">
<tr>
  <%= for column <- columns do %>
  <th><%= column %></td>
  <% end %>
</tr>
<%= for record <- data do %>
<tr>
  <%= for column <- columns do %>
  <td><%= record[ column ] %></td>
  <% end %>
</tr>
<% end %>
</table>

以下のような表示になりました
image.png

複数列データの「列の抽出」

列指定が固定では無くなったので、ここで第2回で行った「列の抽出」をWeb上でも行ってみます

dataから、「name」と「age」の値のみを抽出します

lib/sample_db_web/templates/page/index.html.eex
<%
result = Db.query( "select * from members" )
data = result |> Db.columns_rows
  |> Enum.map( fn( record ) -> %{ "name" => record[ "name" ], "age" => record[ "age" ] } end )
columns = result |> Db.columns
%>
<table border="1">
<tr>
  <%= for column <- columns do %>
  <th><%= column %></td>
  <% end %>
</tr>
<%= for record <- data do %>
<tr>
  <%= for column <- columns do %>
  <td><%= record[ column ] %></td>
  <% end %>
</tr>
<% end %>
</table>

抽出した列の値のみとなりました
image.png

空の列を消すには、columnsの方を「name」と「age」のみとなるようフィルタします

lib/sample_db_web/templates/page/index.html.eex
<%
result = Db.query( "select * from members" )
data = result |> Db.columns_rows
columns = result |> Db.columns
  |> Enum.filter( fn( column ) -> column == "name" || column == "age" end )
%>
<table border="1">
<tr>
  <%= for column <- columns do %>
  <th><%= column %></td>
  <% end %>
</tr>
<%= for record <- data do %>
<tr>
  <%= for column <- columns do %>
  <td><%= record[ column ] %></td>
  <% end %>
</tr>
<% end %>
</table>

抽出した列のみとなりました
image.png

下記のように、「columns」に列名を直接指定することもできます

lib/sample_db_web/templates/page/index.html.eex
<%
result = Db.query( "select * from members" )
data = result |> Db.columns_rows
columns = [ "name", "age" ]
%>
<table border="1">
<tr>
  <%= for column <- columns do %>
  <th><%= column %></td>
  <% end %>
</tr>
<%= for record <- data do %>
<tr>
  <%= for column <- columns do %>
  <td><%= record[ column ] %></td>
  <% end %>
</tr>
<% end %>
</table>

ちなみに、「select文で列指定しない」でも同様の結果にできます(Mnesia版はできません)

外部API呼出のためのライブラリをインストール

では今回の本題、外部API呼出を行います

外部API呼出のために、小粒でピリリなユーティリティライブラリ「smallex」を導入するため、mix.exsの「def deps do」配下に追記します(:phoenix~の記載の上行に追加)

mix.exs
defmodule SampleDb.Mixfile do
  use Mix.Project

  defp deps do
    [
      { :smallex, "~> 0.1" }, 
      
    ]
  end

Smallexおよび関連ライブラリ一通りを取得します(要ネット接続)

mix deps.get

Qiita APIを呼んでQiitaコラム情報をWeb表示する

外部APIとして、Qiitaの検索APIを呼んで、「Elixir」というキーワードが含まれるコラムのリストを取得し、各コラムのID/タイトル/作成日時をWeb表示してみます

SmallexのJsonモジュールを使うと、外部API呼出は、URLのドメインとパスを指定するだけで実行でき、呼出結果もマップリスト化してくれます

更に、「<table~」で始まるHTML部分は、DB表示のものと全く変えていません

つまり、外部APIで取得したデータも、DBと全く同じように扱える点に注目してください

lib/sample_db_web/templates/page/index.html.eex
<%
result = Json.get( "https://qiita.com", "/api/v2/items?query=elixir" )
data = result
columns = [ "id", "title", "created_at" ]
%>
<table border="1">
<tr>
  <%= for column <- columns do %>
  <th><%= column %></td>
  <% end %>
</tr>
<%= for record <- data do %>
<tr>
  <%= for column <- columns do %>
  <td><%= record[ column ] %></td>
  <% end %>
</tr>
<% end %>
</table>

Qiitaから取得したコラムのID/タイトル/作成日時が表示できました
image.png

DB表示と同じHTML部分を使いまわしつつ、外部APIデータのWeb表示ができるようになりました

終わり

いかがでしたでしょうか、Web+APIも、Web+DB同様、とても簡単に実現できました

データ元が、DBだろうが、外部APIだろうが、内部変数だろうが、全てマップリストになってしまうので、画面側は一切、修正が必要ありませんでした

関数型言語によるWeb開発の威力を実感いただけたら幸いです

次回は、いよいよ派手な領域、「Webにグラフ表示」を行います

あと、Advent Calendarの方、明日は、@tuchiro さんの「ElixirでSI開発入門 #4 本番パスワードを環境変数に持たせる」です

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away