御機嫌よう。ガラパゴスのおとめです。
今日は、「次に来る大物Web言語」と前評判の高いElixirと、そのRailsぽいフレームワークPhoenixに触りつつ、RESTful APIを作るには欠かせないSwaggerドキュメントを生成してみようと思います。
あなたは、誰あれ?
はじめに登場人物の簡単な紹介をしておきましょう。
ElixirとPhoenix?
ガラパゴスはスマートフォンアプリの開発を主な事業としている会社です。一口にスマートフォンアプリと言っても、そこは端末だけで完結する世界ではなく、サーバとのやりとりが必要になります。
もちろんサーバーサイドはどんな言語で実装しても構わないのですが、パフォーマンスが気になったり、ホットデプロイしたかったり、煩わしい設定ファイルを書きたくなかったり、JEEが嫌いだったり、ActiveRecordが遅かったり、しますよね?
そんな時、あなたの傍には、ElixirとPhoenixが佇んでいます。
簡単に言うと、関数型ぽい言語にRailsぽいフレームワーク、速くてホットデプロイ上等でめっちゃRails、それがElixir + Phoenixです。Elixirが言語でPhoenixがフレームワーク。と言われても「?」ですね。百聞は一見にしかず、とも申しますゆえ、実際に導入してみましょう。
Swagger?
ガラパゴスはスマートフォンアプリの開発を主な事業としている会社です。一口にスマートフォンアプリと言っても、そこは端末だけで完結する世界ではなく、サーバとのやりとりが必要になります。
でもでも、もしもあなたがサーバーサイドのエンジニアなら、どうやってAPIの仕様を公開するの? どうしたらちゃんとドキュメントのメンテナンスできるの? みたいなことを思いますよね? それに、もしもあなたがアプリのエンジニアなら、サーバにはどんなAPIがあるの? どんな仕様なの? ちょっと試してみたいんだけど? と思いますよね?
そう思った時、あなたの傍にはSwaggerが佇んでいます。
簡単に言うと、RESTful APIの仕様を記述するための仕様、それがSwaggerです。と言われても「?」ですね。百聞は一見にしかず、とも申しますゆえ、実際に導入してみましょう。
環境作成
まだElixirの環境をお持ちでない方も、公式の手順で簡単に用意することができます。Elixirの環境ができたらおもむろにPhonenixもインストールしましょう。
また、Phoenixでは、デフォルトのデータベースがPostgreSQLになっていますので、必要ならインストールします。もしも事情があってPostgreSQLをインストールできない場合、この先の手順が多少変わったり、設定ファイルを変更したりする必要があります。この記事では、PostgreSQLを使えるものとして書いていきます。
なお、PostgreSQLはインストール直後のデフォルト設定ではpostgresユーザーでしか接続できませんので、pg_hba.conf
を適切に変更しておきます。
次にSwagger UIをインストールします。これは、生成したSwaggerドキュメントを表示するために使います。
Swagger UIにはWebサーバが必要ですのでお好みで。ここではnginxを使います。nginxをインストールしたら必要なファイルをコピーします。
$ git clone https://github.com/swagger-api/swagger-ui $ sudo cp -R swagger-ui/dist /var/www/html/
アクセスしたら次のような画面が出てきましたね?
プロジェクトの作成
必要な環境ができたら、いよいよプロジェクトを作ります。もちろん皆様はこの記事をここまで読む間に公式のガイドをチラ見くらいはしていて、すでにRailsをお使いの方なら、めっちゃRailsだとお分かりだと思います。rails new
くらいに気軽に行ってみましょう(ここではswagger_sample_app
としていますが、もちろんお好みの名前をつけることができます)。
$ mix phoenix.new swagger_sample_app
実行すると、Railsをお使いの方にはどこかしら見覚えのある世界が出現すると思います。こんな風に。御機嫌よう世界。
swagger_sample_app +- config +- web | +- controllers | +- models | +- views | +- router.ex +- test +- mix.exs +- mix.lock
この他にもいろいろなファイルやらディレクトリやらができますが、とりあえずここでは、次のような対応が分かればよいでしょう。
Rails | Phoenix |
---|---|
Gemfile | mix.exs |
Gemfile.lock | mix.lock |
config/routes.rb | web/router.ex |
appディレクトリ | webディレクトリ |
なお、Railsのdatabase.yml
などに相当するものはなく、Phoenixでは、config/dev.exs
などの、config
配下の各ステージのファイルに記述していくことになります。
APIの作成
Phoenixでは、scaffoldどーん♪ みたいな感じで、APIも作れます。
$ mix phoenix.gen.json Sample samples foo:integer bar:string
実行したらルーティングとマイグレーションに関するメッセージが表示されたと思います。
まずルーティングの設定をします。メッセージはweb/router.ex
に書いて、みたいなあっさりしたものだったと思いますが、scope
や、今回作成するのはAPIですので、pipe_through :api
なども書く必要があります。
scope "/", SwaggerSampleApp do pipe_through :api resources "/samples", SampleController, except: [:new, :edit] end
次にマイグレーションしましょう。まだデータベースを作っていないので、まずはデータベースの作成から。といってもrake db:create && rake db:migrate
と同じくらいの感じでいけます。
$ mix ecto.create $ mix ecto.migrate
これでCRUDを備えたAPI一式ができてしまいます。さらにはRailsにGrapeを導入した時のようにroutes.rake
をちょっと書くなどというひと手間もなく、作ったAPIのルーティングを確認することができます。
$ mix phoenix.routes page_path GET / SwaggerSampleApp.PageController :index sample_path GET /samples SwaggerSampleApp.SampleController :index sample_path GET /samples/:id SwaggerSampleApp.SampleController :show sample_path POST /samples SwaggerSampleApp.SampleController :create sample_path PATCH /samples/:id SwaggerSampleApp.SampleController :update PUT /samples/:id SwaggerSampleApp.SampleController :update sample_path DELETE /samples/:id SwaggerSampleApp.SampleController :delete
デフォルトのインデックスページのほかに、sample_path
に今回作ったAPIができていますね。早速試してみましょう。
まず、phoenixを起動します。デフォルトでは4000番ポートで起動します。
$ mix phoenix.server
APIをコールしてみます。
$ curl http://127.0.0.1:4000/samples {"data":[]}
まだ何も登録していないので空配列が帰ってきました。
Swaggerドキュメントの作成
さて、APIができたのでドキュメントを公開しましょう。
まず、プロジェクトにSwaggerを導入します。今回はphoenix_swaggerを使ってみます。
# ... defp deps do [# ..., {:phoenix_swagger, path: "~> 0.1.4"}] end # ... def swagger_info do [version: "0.0.0", title: "Swagger sample"] end # ...
依存関係をインストールします。
$ mix deps.get
では、先ほど作成したAPIにドキュメントを書いていきましょう。ここではさわりとして、GET /sampes
のドキュメントを書いてみます。
swagger_model
にAPIの説明を書きます。また、レスポンスの型を明示したい時には、responses
の3番目のパラメタを指定します。このパラメタはfunction/0
ですので、Swaggerに対応したレスポンスを返す関数を書きます。今回の例ではindex_schema
になります。
defmodule SwaggerSampleApp.SampleController do use SwaggerSampleApp.Web, :controller use PhoenixSwagger alias SwaggerSampleApp.Sample plug :scrub_params, "sample" when action in [:create, :update] swagger_model :index do description "登録したレコードの一覧を取得します" responses 200, "一覧", index_schema end def index_schema do %{type: :array, title: "一覧データ", items: %{title: "レコード", type: :object, properties: %{foo: %{type: :integer}, bar: %{type: :string}}} } end def index(conn, _params) do # ...
では、Swaggerで読み込むためのjsonを生成しましょう(プロジェクトのルートディレクトリで実行します)。
$ mix phoenix.swagger.generate
実行すると、swagger.json
が出力されましたね? nginxで表示するために、/var/www/html
あたりにコピーしまして、先ほどブラウザで表示したSwaggerで、おもむろにswagger.json
のURLを入力してExplore
してみましょう。
するとこのように、先ほど書いたドキュメントが出てきましたね?
でも、諸兄諸姉は、RDocやJavadoc、もしかしたら万が一、Excel仕様書などと比べて何がいいのか、などとお思いでありましょう?
CORSの設定
先に進む前に、CORSの設定を行います。SwaggerとPhoexnixは別のサイトになりますので、アクセスを許可する必要があります。
Phoenixの設定
今回はcors_plugを使ってみます。
defp deps do [# ..., {:phoenix_swagger, path: "/path/to/phoenix_swagger"}, {:cors_plug, "~> 1.1"}] end
依存関係のインストールはもうお分かりですね?
$ mix deps.get
READMEにしたがってweb/router.ex
を編集しましょう。
pipeline :api do # originの値は実行するサーバのIPアドレスやDNS名など適切に設定します plug CORSPlug, [origin: "http://example.com"] plug :accepts, ["json"] end # ... scope "/", SwaggerSampleApp do pipe_through :api resources "/samples", SampleController, except: [:new, :edit] options "/samples", SampleController, :options options "/samples/:id", SampleController, :options end
編集したらPhoenixを再起動します。
Swaggerの設定
次に、先ほど生成したswagger.json
を編集しましょう。最後の方に、"host":"localhost:4000"
と書かれていますので、この部分を"host":"example.com:4000"
のように、Phoenixを実行しているサーバのDNS名またはIPアドレスに変更します。
SwaggerからAPIを実行する
さて、皆様はすでにSwaggerの画面上にある「Try it out!」というボタンにお気づきでしょう。ようやくこのボタンを押す時がやってきました。
まあ、まだデータを登録していないので空の配列が帰ってくるのですが、つまりこうやって実際にAPIを叩くこともできるのですね。もちろんパラメタのあるAPIならパラメタを指定することもできるのですが、今回はここまでにしましょう。
さいごに
ガラパゴスでは、業務で使う技術だけでなく、いろいろな言語やツールを試してみちゃう仲間を大絶賛超募集しています。皆様の応募をお待ちしています。
RECRUIT | 株式会社ガラパゴス iPhone/iPad/Androidのスマートフォンアプリ開発
では、御機嫌よう。