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

  • 23
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

はじめに

タイトルのままですが、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