Help us understand the problem. What is going on with this article?

PlugCowboyを使ってみる

More than 1 year has passed since last update.

どうもこんにちは。新しくPlugCowboyが出ましたね。まだまだ開発中みたいですが、早速触ってみました。

そもそもPlugCowboyとは

もともとPlugにはCowboyのAdapterが存在しており、それを経由してErlangで実装されているCowboyとやり取りをしていました。もともとAdapterはPlugプロジェクト内のモジュールとして存在してましたが、今回の変更でPlugCowboyとして別リポジトリとして切り出され、元あったやつは将来的に非推奨になります(現在のmasterではすでに非推奨になっています)。

PlugCowboyを使う

PlugCowboyを使うための事前準備

まずはパッケージをインストールします。現在はhexにはプロジェクトは上がっておらず、gitから直接インストールする必要があります。

mix.exs
  def deps do
    [
      {:plug_cowboy, github: "elixir-plug/plug_cowboy"},
    ]
  end

ちなみにPlugCowboyの依存しているパッケージは以下のものになります。

mix.exs
  def deps do
    [ 
      {:plug, github: "elixir-plug/plug"},
      {:cowboy, "~> 2.5"},
      {:ex_doc, "~> 0.19.1", only: :docs},
      {:hackney, "~> 1.2.0", only: :test},
      {:kadabra, "0.3.4", only: :test}
    ]
  end

Plugはgithub上の最新のものみたいです。cowboyも2.5です。いいですねぇ。
あとはHTTP クライアントでhackney、HTTP/2クライアントでkadabraを使っています。

HTTPリクエスト

では早速アプリケーションを動かしてみましょう。
まずは簡単なものから、一つのモジュールでリクエストとレスポンスを書いてみましょう。

sample.ex
defmodule SandboxPlug.Sample do
  import Plug.Conn

  def init(options) do
    options
  end

  def call(conn, _opts) do
    conn
    |> put_resp_content_type("text/plain")
    |> send_resp(200, "Hello world")
  end
end

では起動させてリクエストを投げてみましょう

> Plug.Cowboy.http SandboxPlug.Sample, []
$ curl http://127.0.0.1:4000
Hello world

無事に起動し、リクエストを投げるところまでできました。
ここで以前と変わったのはhttpの起動の仕方です。
以前は

Plug.Adapters.Cowboy2.http SandboxPlug.Sample, []

でした。今回でAdapterが省略されたのとPlugCowboyを通してCowboyにリクエストを投げるようなりました。

ルーティングの設定

次にルーティングの設定をしてみます。
まずはルーティングを行うモジュールを実装します

router.ex
defmodule SandboxPlug.Router do
  use Plug.Router

  plug :match
  plug :dispatch

  get "/hello" do
    send_resp(conn, 200, "World")
  end

  match _ do
    send_resp(conn, 404, "oops")
  end

end

ここらへんは以前のPlugでの使い方と変わりはありません。
PlugCowboyを使いますが、URLでのルーティング自体はPlugを使います。

次にアプリケーションをみてみましょう。

application.ex
defmodule SandboxPlug.Application do
  use Application

  def start(_type, _opts) do
    children = [
      Plug.Cowboy.child_spec(scheme: :http, plug: SandboxPlug.Router, options: [port: 4000])
    ]
    opts = [strategy: :one_for_one, name: SandboxPlug.Supervisor]
    Supervisor.start_link(children, opts)
  end
end

Supervisorの子プロセスとしてPlugCowboyをプロセスを起動させます。
その中に先ほど上記の方で実装したPlugのルーティングモジュールを指定します。
これで、起動させることでPlugCowboyのプロセスを起動させます。

ではこの状態でアプリケーションを起動させリクエストを投げてみましょう。

$ curl http://127.0.0.1:4410/hello
World
$ curl http://127.0.0.1:4410/fuga
oops

おぉ無事にリクエストを受け付けて、レスポンスを返してくれました。

まとめ

簡単ではありますが、PlugCowboyの実装になります。
Phoenixを使ってると意識しないですが内部ではPlugを使っており、今回の変更は結構、大きい変更になると思います。
Plug自体の中をみるのもPhoenixの挙動を理解するのにかなりオススメです。
次はPlugCowboyの中身を読んでいきたいと思います。

kobatako
fukuokaex
エンジニア/企業向けにElixirプロダクト開発・SI案件開発を支援する福岡のコミュニティ
https://fukuokaex.fun/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした