PerlでAtomPubサーバを作ろう!

第1回 もっとも簡単なAtomPubサーバを作ってみる

この記事を読むのに必要な時間:およそ 6 分

メンバの追加(Create)

メンバの追加 ⁠lib/MyBlog/Controller/EntryCollection.pm)

sub create_entry :Atompub(create) {
    my($self, $c) = @_;

    # スーパークラスが生成したURIと更新日時を取得する
    my $uri    = $self->entry_resource->uri;
    my $edited = $self->edited->epoch; # (UNIX time 形式に変換)

    # POSTされたエントリ本体を取得する (XML::Atom::Entry)
    my $entry = $self->entry_resource->body;

    # entriesテーブルにエントリとメタデータを格納する
    $c->model('DBIC::Entries')->update_or_create({
        edited => $edited,
        uri    => $uri,
        xml    => $entry->as_xml,
    });

    # 成功したらtrueを返す
    return 1;
}

このメソッドが呼ばれる前に,スーパークラスはエントリのURI(EditURI)を決定します。また,エントリにidやlink,app:edited(更新日時)などの要素を適切に追加します。このメソッドが呼ばれた後には,Locationヘッダを設定します。

このメソッドでは,エントリとURI,更新日時をデータベースに格納します。

ここで,上のコードで呼ばれているDBICのupdate_or_createメソッドについて補足します。createではなくこのメソッドが呼ばれているのを奇妙に感じる人もいると思います。確かに,createメソッドを呼ぶのが自然ですし,そのようにして問題ありません。update_or_createを呼んでいる理由は,第3回でエントリのURIを変更するときに説明します。

メンバの取得(Read)

メンバの取得 ⁠lib/MyBlog/Controller/EntryCollection.pm)

sub get_entry :Atompub(read) {
    my($self, $c) = @_;

    # リクエストされたURI
    my $uri = $c->req->uri;

    # entriesテーブルからエントリを検索する
    my $rs = $c->model('DBIC::Entries')->find({ uri => $uri });

    # エントリリソースをセットする
    my $entry = XML::Atom::Entry->new(\$rs->xml);
    $self->entry_resource->body($entry);

    # 成功したらtrueを返す
    return 1;
}

このメソッドでは,リクエストされたURIに対応するエントリを検索して,$self->entry_resource->bodyにセットします。

メンバの更新(Update)

メンバの更新(lib/MyBlog/Controller/EntryCollection.pm)

sub update_entry :Atompub(update) {
    my($self, $c) = @_;

    # リクエストされた URI
    my $uri = $c->req->uri;

    # スーパークラスが生成した更新日時を取得する
    my $edited = $self->edited->epoch; # (UNIX time 形式に変換)

    # PUTされたエントリ本体を取得する (XML::Atom::Entry)
    my $entry = $self->entry_resource->body;

    # entriesテーブルからエントリを検索し,更新する
    $c->model('DBIC::Entries')->search({ uri => $uri })->update({
        edited => $edited,
        xml    => $entry->as_xml,
    });

    # 成功したらtrueを返す
    return 1;
}

POSTの場合と同様に,スーパークラスがエントリに必要な要素を追加します。

このメソッドでは,リクエストされたURIに対応するレコードを検索し,エントリと更新日時を更新してください。

メンバの削除(Delete)

メンバの削除(lib/MyBlog/Controller/EntryCollection.pm)

sub delete_entry :Atompub(delete) {
    my($self, $c) = @_;

    # リクエストされたURI
    my $uri = $c->req->uri;

    # entriesテーブルからエントリを削除する
    $c->model('DBIC::Entries')->search({ uri => $uri })->delete;

    # 成功したらtrueを返す
    return 1;
}

このメソッドでは,リクエストされたURIに対応するレコードを検索し,削除します。

以上でコレクションの作成が終わりました。

コレクションコントローラに関する補足

ここでは,エントリを変更せずにそのままデータベースに格納しましたが,AtomPubの仕様ではサーバはエントリを自由に修正してよいとされています。必要に応じて修正してください。

リソースを操作するときに,HTTPレスポンスヘッダを設定してもかまいません。その場合,スーパークラスがそのヘッダを上書きすることはありません。

Catalystの起動

ここまでで,AtomPubサーバの基本部分は完成です。Catalystを起動します。

MyBlog % perl script/myblog_server.pl

ブラウザから http://localhost:3000/entrycollection にアクセスしてください(Catalystはデフォルトで3000番ポートを使います⁠⁠。次のような空のAtomフィードを取得できると思います。

http://localhost:3000/entrycollection

<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>EntryCollection</title>
  <updated>2008-01-13T18:22:44+09:00</updated>
  <id>http://localhost:3000/entrycollection</id>
  <link rel="self" href="http://localhost:3000/entrycollection"/>
</feed>

今回は,Catalyst::Controller::Atompubの基本的な使い方を説明しました。次回は,画像を扱うコレクションを作成し,写真付きブログサーバとして完成させます。

著者プロフィール

井上武(いのうえたける)

NTTに入社後,未来ねっと研究所でマルチキャストやモバイルIPなどのネットワーク技術の研究開発に取り組んでいたが,最近はWebアーキテクチャに関する仕事をしている。

URLhttp://teahut.sakura.ne.jp/