ちょっと
REST API で操作出来たら便利になりそうだなあと思った部分があったので、maru で実装してみようと思って、Maru ドキュメントの Basic Usage を写経してみたメモです。
◯ (Maru)
先日の fukuoka.ex で教えて頂きました。
www.slideshare.net
特徴については、上記資料の 6 ページに簡潔に纏まっていますので転載させて頂きます。
有難うございます。
Ruby の grape という REST API ライクな API を生成するフレームワークにインスパイヤされているらしい。grape 自体初耳でした。
Basic Usage 写経
写経した環境
$ sw_vers ProductName: Mac OS X ProductVersion: 10.11.6 BuildVersion: 15G1421 $ iex -v Erlang/OTP 19 [erts-8.3] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace] IEx 1.4.4
新規アプリケーションの作成
$ mix new oreno_app
以下のように出力されます。
$ mix new oreno_app * creating README.md * creating .gitignore * creating mix.exs * creating config * creating config/config.exs * creating lib * creating lib/oreno_app.ex * creating test * creating test/test_helper.exs * creating test/oreno_app_test.exs Your Mix project was created successfully. You can use "mix" to compile it, test it, and more: cd oreno_app mix test Run "mix help" for more commands.
mix.exs に依存するモジュール名を定義
mix.exs に以下を追記する。
defp deps do [ {:maru, "~> 0.11"} ] end
アプリケーションの実装
lib/oreno_app.ex に以下のように実装します。
defmodule OrenoApp.Router.Homepage do use Maru.Router get do json(conn, %{ hello: :maru }) end end defmodule OrenoApp.API do use Maru.Router plug Plug.Parsers, pass: ["*/*"], json_decoder: Poison, parsers: [:urlencoded, :json, :multipart] mount OrenoApp.Router.Homepage rescue_from :all do conn |> put_status(500) |> text("Server Error") end end
アプリケーションを起動させる為の設定
config/config.exs に以下を追記します。
config :maru, OrenoApp.API, http: [ip: {0, 0, 0, 0}, port: 8881]
ip: {0, 0, 0, 0}
を追加しない場合、デフォルトでは 127.0.0.1 でのみ Listen するので Docker で動かす場合等は注意しませう。
アプリケーションの起動
依存するモジュールの導入 (maru の導入)
$ mix deps.get
以下のように出力されます。
$ mix deps.get Running dependency resolution... Dependency resolution completed: cowboy 1.1.2 cowlib 1.0.2 maru 0.11.4 mime 1.1.0 plug 1.3.5 poison 3.1.0 ranch 1.3.2 * Getting maru (Hex package) Checking package (https://repo.hex.pm/tarballs/maru-0.11.4.tar) ...
サーバーの起動
$ iex -S mix
以下のように出力され、コンパイルが走ります。
$ iex -S mix Erlang/OTP 19 [erts-8.3] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace] ==> poison Compiling 4 files (.ex) Generated poison app ===> Compiling cowlib src/cow_multipart.erl:392: Warning: crypto:rand_bytes/1 is deprecated and will be removed in a future release; use crypto:strong_rand_bytes/1 ... 09:40:54.442 [info] Starting Elixir.OrenoApp.API with Cowboy on http://0.0.0.0:8881 Interactive Elixir (1.4.4) - press Ctrl+C to exit (type h() ENTER for help) iex(1)>
Cowboy という Web サーバーが起動します。
Hello Maru
Web サーバーが起動したら API にアクセスしてみる。
$ curl http://127.0.0.1:8881 -w '\n' -i HTTP/1.1 200 OK server: Cowboy date: Sat, 17 Jun 2017 01:02:15 GMT content-length: 16 cache-control: max-age=0, private, must-revalidate content-type: application/json; charset=utf-8 {"hello":"maru"}
やったー。
Basic Usage + アルファ
プラスアルファ
- Docker で動かしたい
Dockerfile
mix deps.get
等がそのまま利用出来ないので焦ったものの、以下のような Dockerfile で一通り動かせることを確認しました。
ROM elixir ADD ./ /app WORKDIR /app RUN mix local.hex --force && mix deps.get EXPOSE 8881 CMD ["mix", "run", "--no-halt"]
あと、フォアグラウンドで Web サーバーを動かす方法についても悩みましたが、mix run --no-halt
でいけるようです。
docker-compose.yml
version: '2' services: hello_maru: build: ./ volumes: - ./:/app ports: - "8881:8881"
Docker 環境でも Hello Maru
ビルドして…
$ docker-compose build Building hello_maru Step 1/6 : FROM elixir ---> 066128183b87 Step 2/6 : ADD ./ /app ---> f5e8affa64c7 Removing intermediate container 6cde27f8f51f Step 3/6 : WORKDIR /app ---> 9c269ced9d4f ... Removing intermediate container 01de153aa0ac Successfully built 8cadb37872f7
Run すると…
$ docker-compose up -d Creating network "orenoapp_default" with the default driver Creating orenoapp_hello_maru_1 $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0ecfa2a6d96b orenoapp_hello_maru "mix run --no-halt" 11 seconds ago Up 9 seconds 0.0.0.0:8881->8881/tcp orenoapp_hello_maru_1
Hello Maru.
$ curl http://127.0.0.1:8881 -w '\n' -i HTTP/1.1 200 OK server: Cowboy date: Sat, 17 Jun 2017 01:02:45 GMT content-length: 16 cache-control: max-age=0, private, must-revalidate content-type: application/json; charset=utf-8 {"hello":"maru"}
本当に
丸っと 10 分くらいで Maru を体験することが出来ました。
こちらの写経については、進捗が芳しくありません。ボチボチやっていきます。