Skip to content

Instantly share code, notes, and snippets.

@voluntas
Last active December 13, 2015 22:48
Show Gist options
  • Save voluntas/f99838001efced196fc0 to your computer and use it in GitHub Desktop.
Save voluntas/f99838001efced196fc0 to your computer and use it in GitHub Desktop.
Webmachine のススメ

Webmachine のススメ

更新:2013-03-15
イベント:Python Developers Festa 2013.03
発表日時:2013-03-16
バージョン:0.0.11
作者:@voluntas
URL:http://voluntas.github.com/

アジェンダ

  • 自己紹介
  • Webmachine って何?
  • こんにちは、Webmachine
  • リソース関数

自己紹介

ag:

$ git clone git://github.com/erlang/otp.git
$ cd otp
$ ag voluntas .

Webmachine って何?

Basho Technologies, Inc が開発している REST ツールキットです。フレームワークではありません。 あくまでツールキットなので、これをベースに作り上げる必要があります。

Webmachine にはテンプレートエンジンや O/R マッパーのようなモノは含まれていません。さらには JSON の変換すらも含まれていません。あくまで REST の概念を処理するエンジンを実装したものです。

URL ディスパッチャーと REST エンジン、それだけです。認証やセッションの仕組みもありません。

なのでフレームワークでは無くツールキットなのです。

どこで使われてるの?

凄く使われているわけではありません ... 。

  • Chef Hosting
  • GitHub Pages
  • Riak HTTP API

何が嬉しいの?

RESTful な実装をする場合は厳密な仕様を意識する必要があります。それらをほとんど考える必要なく、コールバックを指定していくだけで簡単に RESTful な仕組みを実現する事が出来ます。

Erlang 専用なの?

本家 Webmachine は Erlang で書かれていますが、考え方はとてもシンプルなため様々な言語で実装されています。GitHub で webmachine で検索すればほとんどの言語での実装が出てきます。

Ruby / Python / Haskell / Node.js / Perl / Go / Scala / Clojure / Java

ちなみに Basho 自体がメンテナンスしているのは Erlang 版だけです。

こんにちは、Webmachine

まずはコードを見てもらいましょう

-module(pyfes_wm_hello).
-export([init/1]).
-export([to_html/2]).

-include_lib("webmachine/include/webmachine.hrl").

init([]) ->
    {ok, undefined}.

to_html(ReqData, State) ->
    {"<html><body>こんにちは、Webmachine</body></html>", ReqData, State}.

実はこのコード、一つ省略されていてわかりにくいんです。

明示的に書いたコードは以下になります

-module(pyfes_wm_hello).
-export([init/1,
         content_types_provided/2]).
-export([to_html/2]).

-include_lib("webmachine/include/webmachine.hrl").

init([]) ->
    {ok, undefined}.

content_types_provided(ReqData, State) ->
    {[{"text/html", to_html}], ReqData, State}.

to_html(ReqData, State) ->
    {"<html><body>こんにちは、Webmachine</body></html>", ReqData, State}.

content_types_provided/2 は実は to_html/2 を呼び出しています。 これはデフォルトが to_html/2 のため、省略されています。

content_types_provided/2

content_types_provided/2 とは何なんでしょう。

これはレスポンスに何を返すか mediatype によって判断されます。

Content-Type で判断します。

たとえば JSON を返す場合は以下の様にします

content_types_provided(ReqData, State) ->
    {[{"application/json", to_json}], ReqData, State}.

to_json(ReqData, State) ->
    {"[1,2,3]", ReqData, State}.

ここの判定は Accept が使用されて判定されます。

content_types_provided/2 はどんな形式で返して欲しいかを mediatype によって定義する関数です。

リソース関数

content_types_provided/2 のように Webmachine にはいくつものリソースを操る関数があります。

Resource Functions
https://github.com/basho/webmachine/wiki/Resource-Functions

いくつか紹介していきましょう。

resource_exists/2

resource_exists/2 はリソースが存在するかどうかを確認する関数です。戻り値は boolean() です。

存在しない場合は 404 を返します。

resource_exists(ReqData, State) ->
    case lookup_resource(...) of
        not_found ->
            {false, ReqData, State};
        Value ->
            {true, ReqData, State#state{resource = Value}
    end.

allowed_methods/2

allowed_methods/2 は処理可能なメソッドを atom() で定義します。

対応していない場合は 415 を返します。

allowed_methods(ReqData, State) ->
    {['GET', 'POST', 'DELETE'], ReqData, State}.

delete_resource/2

delete_resource/2 は DELETE メソッドが送られてきた場合に呼ばれる関数です。

この関数が呼ばれる前に resource_exists/2 でリソースの存在チェックはされているので、 リソースが存在しない事を考えて実装する必要はありません。

delete_resource(ReqData, #state{resource = Value} = State) ->
    ok = delete_resource(Value),
    {true, ReqData, State}.

リソース関数の呼び出し順番

図があるのでそちらを見て貰えれば良いです。

Webmachine コトハジメ

デモ

https://gist.github.com/voluntas/4363064

Webmachine を使ったホットスワップ

デモ

https://gist.github.com/voluntas/5002689

参考

A REST-based system for building web applications.
https://github.com/basho/webmachine
Webmachine and RESTful Web Frameworks with Justin Sheehy
http://www.infoq.com/interviews/webmachine-and-restful-web-frameworks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment