Elixir
Phoenix

Elixir+PhoenixでGCMのAPIを叩いてPush通知を送る簡単なAPIをつくってみた

More than 3 years have passed since last update.


はじめに

タイトルのままですが、Elixir+PhoenixでGCMサーバーのAPIを叩いてPush通知を送る簡単なWebAPIをつくってみました。


経緯

僕自身は普段CakePHPで開発することが多いのですが、最近はスマホアプリ全盛(あとSPA。今後はIoT?)でMVCなWebアプリを開発する機会が減ってきていて、サーバー側はRestなWebAPIを開発することが多くなってきています。

そうするとCakePHPはフルスタック過ぎるし、もっと高性能なAPIサーバーつくりたいなと思いながらもGolangは乗り遅れちゃったし、Node.jsはたまに使うけど個人的に肌なじみがあまりよくなく、何かイケてる言語ないかなぁと悶々としていたところ、@naoya@githubさんが紹介していたスライドをみて興味を持ちました。

言語的な特徴には触れない(他の方が語っていること以外は語れない)ので、他の方の投稿を参照してください。


環境構築


インストール on Mac

brewで簡単に入れられます。

$ brew install elixir


Hello, world!

iexコマンドでコマンドプロンプトで対話的に実行出来ます。

rubyのirbコマンドと同じです。

$ iex

iex(1)> IO.puts "Hello, world!"

Hello, world
:ok

ここまでは楽勝。


Phoenixインストール 

現状最もメジャーなフレームワークであるPhoenixをインストールします。

APIサーバーつくりたいだけなので、Railsライクなのはややオーバースペックな気もしますが、馴染みやすいので入り口としてはよいかなと思っています。

$ mix archive.install https://github.com/phoenixframework/phoenix/releases/download/v1.0.3/phoenix_new-1.0.3.ez


アプリ作成 / 起動

Phoenixアプリをつくります。

mixコマンドはRailsで言うrailsコマンドです。

$ mix phoenix.new gcm_app

サーバー起動もRails的な感じ。

アプリのルートディレクトリに移動してから下記コマンドを実行します。

$ mix phoenix.server

Unchecked dependencies for environment dev:
* phoenix_live_reload (Hex package)
the dependency is not available, run `mix deps.get`
* cowboy (Hex package)
the dependency is not available, run `mix deps.get`
* phoenix_html (Hex package)
the dependency is not available, run `mix deps.get`
* phoenix (Hex package)
the dependency is not available, run `mix deps.get`
* postgrex (Hex package)
the dependency is not available, run `mix deps.get`
* phoenix_ecto (Hex package)
the dependency is not available, run `mix deps.get`
** (Mix) Can't continue due to errors on dependencies

依存パッケージあたりでエラーになってしまった。。

言われた通りに以下を実行します。

$ mix deps.get

依存パッケージのチェックをしてくれる模様。

再度サーバー起動してみると、成功したっぽい。

http://localhost:4000/

上記URLでWelocome to Phoenix!なページが表示されます。

phoenix_20151105.png


API開発


HTTPクライアントインストール

HTTPクライアントであるHTTPoisonを入れます。

~mix.exsのdepsの箇所にHTTPoisonの設定を追加します。


mix.exs

  defp deps do

[{:phoenix, "~> 1.0.3"},
{:phoenix_ecto, "~> 1.1"},
{:postgrex, ">= 0.0.0"},
{:phoenix_html, "~> 2.1"},
{:phoenix_live_reload, "~> 1.0", only: :dev},
{:cowboy, "~> 1.0"},
{:httpoison, "~> 0.7.2"}]
end

そして、依存パッケージインストール。

$ mix deps.get

インストール後、~mix.exsのapplicationの箇所にもHTTPoisonの設定を追加します。

これで実行時HTTPoison.startが不要になるっぽい。


mix.exs

  def application do

[mod: {GcmApp, []},
applications: [:phoenix, :phoenix_html, :cowboy, :logger,
:phoenix_ecto, :postgrex, :httpoison]]
end


ルーター設定

デフォルトのAPI用のルーター設定はコメントアウトされているので、以下のように修正します。


router.ex

  scope "/api", GcmApp do

pipe_through :api

get "/push/:message/", PageController, :push
end



メイン処理

~web/controllers/page_controller.exにpushメソッドを以下のように追加します。

GCMの仕様については省略。


page_controller.ex

  def push(conn, %{"message" => message}) do

url = "https://android.googleapis.com/gcm/send"
api_key = "********"
registraion_ids = ["hogehogehogehoge"]

headers = [{"Content-Type", "application/json;charset=UTF-8"},
{"Authorization", "key=#{api_key}"}]
json_data = %{collapse_key: "ff1",
delay_while_idle: true,
time_to_live: 864000,
data: %{title: "gcm_app", message: message},
registration_ids: registraion_ids} |> Poison.encode!

# HTTPoison.start # 不要だった
response = HTTPoison.post!(url, json_data, headers)
# IO.puts response.body # デバッグ用

case response do
%{status_code: 200, body: body} -> json conn, Poison.decode!(body)
%{status_code: code} -> json conn, %{error: code}
end

end



API実行

開発が完了したら、サーバーを起動してAPIを実行!

成功した場合、下記のようなレスポンスが返ってきます。

$ curl http://localhost:4000/api/push/finalfantasy

{"success":1,"results":[{"message_id":"0:1446717643350281%3207dc8500018b71"}],"multicast_id":9177386917145341445,"failure":0,"canonical_ids":0}

そして、Androidアプリに"finalfantasy"というPushメッセージが通知されます。


テスト

ユニットテストについては次の機会に←


まとめ

Elixir(と言うか新しい言語)たのしい!

でも、まずは動かしてみたレベルなので、まだまだ文法とか内部構造とか理解していないので、これから勉強していこう。ベンチマークもとりたいな。


参考文献 / 参考URL

Elixir ご紹介:

https://speakerdeck.com/naoya/elixir-goshao-jie

Installing Elixir:

http://elixir-lang.org/install.html

Elixir 基礎文法最速マスター:

http://qiita.com/niku/items/729ece76d78057b58271

Elixir のパターンマッチを攻略しよう:

http://qiita.com/naoya@github/items/9da982febe89d83cb5b5

Installation · Phoenix:

http://www.phoenixframework.org/docs/installation

Phoenix アプリケーションを作成する:

http://qiita.com/mserizawa/items/a861b4aa0d55b42b2324

edgurgel/httpoison:

https://github.com/edgurgel/httpoison

ElixirのHTTPoisonライブラリの使い方:

http://qiita.com/ColdFreak/items/4beb6cacfbb39baa955f

Phoenix で外部 API にリクエストする API を作る:

http://qiita.com/mserizawa/items/3ac483aca4f2926fa1a9

『WEB+DB PRESS Vol.88』(技術評論社):

http://gihyo.jp/magazine/wdpress/archive/2015/vol88