スポンサーリンク

2015年8月23日

[Backend Phoenix]cURLでクールにPhoenix-FrameworkとHTTP通信する

Goal

curlからPhoenixへHTTP通信をする。

Dev-Environment

OS: Windows8.1
Erlang: Eshell V6.4, OTP-Version 17.5
Elixir: v1.0.4
Phoenix Framework: v0.17.0
PostgreSQL: postgres (PostgreSQL) 9.4.4
cURL: v7.41.0 (i386-pc-win32)

Wait a minute

はい・・・では、Backend Phoenixの第一回目の記事です。
まったく、Tutorialもまだv1.0さえ出してないのに、
自分で仕事を増やしてどうするんですかね?(嬉しい顔)
まぁ、私はドが付くMなので、いいんですけど(笑)
そうじゃなきゃ、自衛隊なんて行ってません(任期制でしたけど)
この記事でやることについて、少々書いておきます。
curlからPhoenixへHTTP通信をします。
Phoenix-Framework側はバックエンドとし、JSONデータで通信を取るAPIサーバとして扱います。
(この時点ではAPIサーバと言えるほどではないでしょうけど・・・)
今回は、フロントエンドはなし。
しかし、HTTP通信を取るために、タイトルにもあるcURLコマンドを使います。
cURLをフロントエンドと言い張るのは、激しく違和感がありますから・・・
cURLコマンドからJSON形式のデータを送り、DBへデータの登録。
また、cURLコマンドから指定したDBデータをJSON形式で取得します。

Index

HTTP communication to Phoenix from curl
|> Preparation
|> JSON API using Phoenix
|> HTTP communication use the curl

Preparation

プロジェクトの作成をします。
>cd プロジェクト作成ディレクトリ
>mix phoenix.new api_sample
>cd api_sample
>mix ecto.create
>mix phoenix.server
>ctrl+c
また、WindowsでcURLコマンドを使えるようにします。
WindowsでcURLコマンド?っと疑問がある人もいるでしょう。
これを使えばWindowsでもcURLコマンドが使えるようになります。
ダウンロード: cURL - Download
インストールから使い方までの参考は以下のリンク先が丁寧に書いてあります。
参考: Windows環境にcURLコマンドを実行できるようにインストールする手順

JSON API using Phoenix

Phoenix側でJSON APIを取り扱えるように構築をします。
コマンド使えば、すぐできます。
>mix phoenix.gen.json Post posts title:string content:string
* creating priv/repo/migrations/20150823103956_create_post.exs
* creating web/models/post.ex
* creating test/models/post_test.exs
* creating web/controllers/post_controller.ex
* creating web/views/post_view.ex
* creating test/controllers/post_controller_test.exs
* creating web/views/changeset_view.ex

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

    resources "/posts", PostController

and then update your repository by running migrations:

    $ mix ecto.migrate
ルーティングを追加します。

ファイル: web/router.ex

apiのコメントアウトを外し、示されたルーティングをコピペします。
defmodule ApiServer.Router do
  use ApiServer.Web, :router

  ...

  pipeline :api do
    plug :accepts, ["json"]
  end

  ...

  # Other scopes may use custom stacks.
  scope "/api", ApiServer do
    pipe_through :api

    resources "/posts", PostController
  end
end
マイグレーションを実行。
>mix ecto.migrate

== Compilation error on file web/views/post_view.ex ==
** (SyntaxError) web/views/post_view.ex:14: syntax error before: title
    (elixir) lib/kernel/parallel_compiler.ex:97: anonymous fn/4 in Kernel.ParallelCompiler.spawn_compilers/8
ん?何かコンパイルエラー出た。
自動生成されたビューモジュールだな。
見に行く・・・
ここが原因のようだ。

ファイル: web/views/post_view.ex

,(カンマ)の区切りが付いてない。
修正前:
def render("post.json", %{post: post}) do
  %{id: post.id
    title: post.title
    content: post.content}
end
修正後:
def render("post.json", %{post: post}) do
  %{id: post.id,
    title: post.title,
    content: post.content}
end
もしかして初めてプルリク出せるんじゃね!?
って思っていた時間が私にもありましたよ。
調べてみたところ、既に直ってるようですね。
参考: ハードリカーエンジニア - PhoenixframeworkChanges-20150820
参考: Github - phoenixframework/phoenix -
では改めて、マイグレーションを実行。
>mix ecto.migrate

20:24:37.783 [info]  == Running ApiServer.Repo.Migrations.CreatePost.change/0 forward

20:24:37.783 [info]  create table posts

20:24:37.813 [info]  == Migrated in 0.2s
無事にマイグレーション完了。問題なしですね。
ちょっと生成されたソースを見てみました。
テンプレートがなく、ビューからjsonでレンダリングしているみたいですね。

HTTP communication use the curl

cURLを使いクールにHTTP通信を行います。
Phoenixを起動しておきます。
>mix phoenix.server
端末をもう一つ立ち上げます。
ルーティング先を確認します。
>cd .../api_sample
>mix phoenix.routes
page_path  GET     /                    ApiServer.PageController :index
post_path  GET     /api/posts           ApiServer.PostController :index
post_path  GET     /api/posts/:id/edit  ApiServer.PostController :edit
post_path  GET     /api/posts/new       ApiServer.PostController :new
post_path  GET     /api/posts/:id       ApiServer.PostController :show
post_path  POST    /api/posts           ApiServer.PostController :create
post_path  PATCH   /api/posts/:id       ApiServer.PostController :update
           PUT     /api/posts/:id       ApiServer.PostController :update
post_path  DELETE  /api/posts/:id       ApiServer.PostController :delete
それでは、cURLコマンドを使います。
>curl -H "Accept: application/json" -H "Content-Type: application/json" http://localhost:4000/api/posts
{"data":[]}
まだデータを一件も入れていないので、データの内容は何も返ってきませんね。
データを登録します。
>curl -v -H "Accept: application/json" -H "Content-Type: application/json" -X POST -d "{ \"post\": { \"title\": \"hogehoge\", \"content\": \"hugehuge\" } }" http://localhost:4000/api/posts
*   Trying ::1...
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 4000 (#0)
> POST /api/posts HTTP/1.1
> User-Agent: curl/7.41.0
> Host: localhost:4000
> Accept: application/json
> Content-Type: application/json
> Content-Length: 58
>
* upload completely sent off: 58 out of 58 bytes
< HTTP/1.1 201 Created
< connection: keep-alive
< server: Cowboy
< date: Sun, 23 Aug 2015 12:12:34 GMT
< content-length: 57
< content-type: application/json; charset=utf-8
< cache-control: max-age=0, private, must-revalidate
< x-request-id: 6cc91u25k3ntdt6ng76sc55d0d0hfbvo
<
{"data":{"title":"hogehoge","id":1,"content":"hugehuge"}}* Connection #0 to host localhost left intact
Caution:
Windows版のcURLですが何と!?
コマンドラインから複数行のJSONデータを渡すことができません><
正確に言うと渡すのが面倒です。
どうしてもコマンドラインから渡す場合は、
JSONデータ内の”(二重引用符)を\(円マーク)でエスケープする必要があるみたいです。
(もしくはバックスラッシュでエスケープ)
・・・クールじゃねぇ~orz
何にせよ無事(?)登録できたようなので、
次は単一データの取得をしてみます。
>curl -H "Accept: application/json" -H "Content-Type: application/json" http://localhost:4000/api/posts/1
{"data":{"title":"hogehoge","id":1,"content":"hugehuge"}}
よし、無事取得できました。
ついでなので、全件データを取得してみます。
一件しかないけど(笑)
>curl -H "Accept: application/json" -H "Content-Type: application/json" http://localhost:4000/api/posts
{"data":[{"title":"hogehoge","id":1,"content":"hugehuge"}]}
こっちも取得に問題はありませんね。

Speaking to oneself

今回はここまで~
キャスター「龍之介、どうでした?( ^,_ゝ^)ニコッ」
龍之介「旦那!!ク~~ルだぜ~~ヾ(*´∀`*)ノキャッキャ」
さて下らない冗談はさておき。(ネタが古い・・・)
cURLから通信を取ることができました!!
お次は、mithril.jsをフロントエンドとして使って通信を取ってみます!!
と行きたいのですが、mithril.js使ったことないんですorz
なので、習得するまで待って!お願いしますm(_ _)m
チュートリアル(?)見る限りは、そんなに難しくはないと思う。
それに、すぐ習得できるのが売りの一つらしいので(笑)
私が使う程度のレベルなら、そんなに日数はいらないでしょう。きっと・・・
そんなわけで、次はjsでUI部分を作っていきます。
早く、スマフォアプリまで辿り着きたいな~ヾ(*´∀`*)ノキャッキャ
今回のプロジェクトはGithubにアップしています。
Github: darui00kara/backend_phoenix (curl)

Bibliography

人気の投稿