AtomPubって何だ
参考資料
AtomPubに興味が出てきました.ってことで,色々調べてみてるんですがどうも要領を得ません.RFCになったばかりでI-D時代の説明や実装が多いからなのかな,と思ってるんですが実際のところは調査不足かと.とりあえず,読んでおかないといけなさそうな資料をまとめました.
- Atom Publishing Protocol 日本語訳
- Atom Publishing Protoclを試す cURL
- Atom Publishing Protocolのメモ
- Atom出版プロトコルを使ってWebリソースを作成し,編集する
- Studying HTTP
- APP Test Site Service Document URI
- APP Test Site Specification
で,これらをもとにちょっと試してみて,うまく行ったところをメモしてみました.
APP Test Siteを試してみる
Atom Publishing Protoclを試す cURLを読んで,cURLを使えばAtomPubを試せるとわかったので,APP Test Site Specificationで試してみました.まず,記事通りにサービスドキュメントを取得しました.
curl -s "http://bitworking.org/projects/apptestsite/app.cgi/service/;service_document"
そうすると次のデータが返ってきます.
<?xml version="1.0" encoding="utf-8"?> <service xmlns="http://www.w3.org/2007/app" xmlns:atom="http://www.w3.org/2005/Atom"> <workspace> <atom:title>AtomPub Test Site</atom:title> ... <collection href="media/"> <atom:title>media</atom:title> <accept>*/*</accept> <categories fixed="yes" /> </collection> ... </workspace> </service>
これからわかるのはworkspace titleが"AtomPub Test Site"で,"media collection URI"が"http://bitworking.org/projects/apptestsite/app.cgi/service/media/"ということです.次に,curlを実行するディレクトリに"catalyst_logo.png"を用意してからmedia collectionに画像をuploadしました.
curl -s -H Content-Type:image/png --data-binary @catalyst_logo.png \ -X POST "http://bitworking.org/projects/apptestsite/app.cgi/service/media/"
このコマンドを実行した結果返ってくるのが次のxml.
<?xml version="1.0" encoding="utf-8"?> <entry xmlns="http://www.w3.org/2005/Atom" xmlns:app="http://www.w3.org/2007/app"> <title /> <link href="http://bitworking.org/news/460/" /> <id>http://bitworking.org/news/460/</id> <author> <name>Joe Gregorio</name> </author> <updated>2008-02-10T23:39:12.614612-04:00</updated> <app:edited>2008-02-10T23:39:12.614612-04:00</app:edited> <summary type="xhtml"> <div xmlns="http://www.w3.org/1999/xhtml" /> </summary> <link href="." rel="edit" /> <link href=";media" rel="edit-media" /> <content src="http://bitworking.org/images/dev/460-.png" type="image/png" /> </entry>
これからわかるのが,
- collection URI: http://bitworking.org/projects/apptestsite/app.cgi/service/media/
- entry resource: http://bitworking.org/projects/apptestsite/app.cgi/service/media/
- media resource: http://bitworking.org/projects/apptestsite/app.cgi/service/media/;media
ということです.でもこれはなんだか変です.よく見ると,
<link href="." rel="edit" /> <link href=";media" rel="edit-media" />
となっていますが,元の記事から類推すると,
<link href="460/" rel="edit" /> <link href="460/;media" rel="edit-media" />
のようになるはずです.この場合,entry resourceとmedia resourceは以下のようになるはずです.
- collection URI: http://bitworking.org/projects/apptestsite/app.cgi/service/media/
- entry resource: http://bitworking.org/projects/apptestsite/app.cgi/service/media/460/
- media resource: http://bitworking.org/projects/apptestsite/app.cgi/service/media/460/;media
もう一回GETしてみたら
curl -s "http://bitworking.org/projects/apptestsite/app.cgi/service/media"
確かにそうなっているみたいです.何が起こっているんでしょうか.追記:たけまるさんに,APP Test Siteのバグだと教えてもらいました.バグ報告も上がってるんだけど,スルーされてるらしい
<?xml version="1.0" encoding="utf-8"?> <feed xmlns="http://www.w3.org/2005/Atom" xmlns:app="http://www.w3.org/2007/app"> <title type="text">BitWorking | Joe Gregorio</title> <link href="http://bitworking.org/projects/apptestsite/app.cgi/service/media" rel="self" /> <link href="http://bitworking.org/" rel="alternate" /> <link href="?page=1" rel="next" /> <icon>http://bitworking.org/favicon.ico</icon> <updated>2008-02-10T23:39:12.614612-04:00</updated> <author> <name>Joe Gregorio</name> </author> <id>http://bitworking.org/</id> <entry> <title /> <link href="http://bitworking.org/news/460/" /> <link href="460/" rel="edit" /> <link href="460/;media" rel="edit-media" /> <id>http://bitworking.org/news/460/</id> <updated>2008-02-10T23:39:12.614612-04:00</updated> <app:edited>2008-02-10T23:39:12.614612-04:00</app:edited> <summary type="xhtml"> <div xmlns="http://www.w3.org/1999/xhtml" /> </summary> <link href="460/;media" rel="edit-media" /> <content src="460/;media" type="image/png" /> </entry> ... </feed>
資料によると,Atomエントリを更新するには"entry resource"に"PUT"を実行,uploadした画像を変更するには"media resource"に"PUT"を実行,Atomエントリを削除するには"DELETE"を実行して,削除できたかどうかを確認するには"collection uri"をGETすることになります.というわけで,画像を変更してみました.
curl -s -H Content-Type:image/png --data-binary @ape_logo.png \ -X PUT "http://bitworking.org/projects/apptestsite/app.cgi/service/media/460/;media"
何の出力もなく,"http://bitworking.org/images/dev/460-.png"の画像が変わっていました.If-Match ヘッダを付ける必要があるのかと思ったんだけど,そこら辺がちょっと謎な点です.で,実際に削除するにはどうすればいいのかと思ってやってみました.
curl -s -X DELETE "http://bitworking.org/projects/apptestsite/app.cgi/service/media/460/;media"
画像だけ消せるかどうかをまず試してみると,
<h1>That action is not allowed on this resource.</h1>
ということで失敗.ということで,エントリ全部を削除してみると,
curl -s -X DELETE "http://bitworking.org/projects/apptestsite/app.cgi/service/media/460/"
成功です."http://bitworking.org/images/dev/460-.png"へのアクセスもできなくなりました.
Catalyst::Controller::Atompubで試してみる
たけまる / Catalyst::Controller::Atompub リリースを読んで,Catalyst::Controller::Atompubを使って作ったMyAtomをテーゲットにしてcURLを使ってみました.
curl -s "http://localhost:3000/myservice"
ここでもサービスドキュメントを取得しています.これで返ってくるのはこんなデータ.
<?xml vrsion="1.0" encoding="utf-8"?> <service xmlns="http://www.w3.org/2007/app"> <workspace> <atom:title xmlns:atom="http://www.w3.org/2005/Atom">MyAtom</atom:title> <collection href="http://localhost:3000/mycollection"> <atom:title xmlns:atom="http://www.w3.org/2005/Atom">MyCollection</atom:title> </collection> </workspace> </service>
これから"collection url"が"http://localhost:3000/mycollection"だと言う事がわかりました.
curl -s -H Content-Type:image/png --data-binary @catalyst_logo.png \ -X POST "http://localhost:3000/mycollection"
で,こちらも同様に画像をuploadしようとしてみると,
<?xml version="1.0" encoding="utf-8"?> <entry xmlns="http://www.w3.org/2005/Atom"> <link rel="related" href="http://localhost:3000/mycollection"/> <updated>2008-02-11T17:47:42+09:00</updated> <title>415 Unsupported media type: image/png</title> <content type="xhtml"> <div xmlns="http://www.w3.org/1999/xhtml">415 Unsupported media type: image/png</div> </content> </entry>
失敗しました.どうやらxmlしかuploadできないようです.たけまる / Perl - Atompub 0.0.1 リリースを見るとXML::Atom::Entryモジュールを使えば必要なxmlを用意できるようです.
perl -MXML::Atom::Entry -le '$e = XML::Atom::Entry->new; \ $e->title("New Entry"); $e->content("Content of my entry"); print $e->as_xml'
これを実行してみてできるxmlファイルはこんな感じ.
<?xml version="1.0" encoding="utf-8"?> <entry xmlns="http://purl.org/atom/ns#"> <title>New Entry</title> <content mode="xml"> <div xmlns="http://www.w3.org/1999/xhtml">Content of my entry</div> </content> </entry>
ここで注意しないといけないのは"Content-Type".curlがデフォルトで使っている"Content-Type"ではuploadできないので,明示的に"application/atom+xml"と指定する必要があります.元々フォームデータをuploadするためのツールでしょうからね.
curl -s -H Content-Type:application/atom+xml \ --data-binary @- -X POST "http://localhost:3000/mycollection"
ちなみに,"--data-binary @-"となっているのはvim上で実行しているからです.上のxmlファイルを"visual mode"で指定(vで開始位置指定,hjklで移動,:で確定)して外部コマンド呼び出しをしています.
:'<,'>! curl -s -H ...
こんな感じ.で,返ってきたxmlはこうなります.
<?xml version="1.0" encoding="utf-8"?> <entry xmlns="http://purl.org/atom/ns#"> <title>New Entry</title> <content mode="xml"> <div xmlns="http://www.w3.org/1999/xhtml">Content of my entry</div> </content> <app:edited xmlns:app="http://www.w3.org/2007/app">2008-02-11T19:10:36+09:00</app:edited> <modified>2008-02-11T19:10:36+09:00</modified> <id>http://localhost:3000/mycollection/20080211-191036-985610.atom</id> <link xmlns="http://www.w3.org/2005/Atom" rel="edit" href="http://localhost:3000/mycollection/20080211-191036-985610.atom"/> </entry>
この場合の"entry resource"はサーバが任意に指定しています(mycollection/20080211-191036-985610.atom)が,Slugを使うと作成するエントリのURIを指定することができます.
curl -s -H Content-Type:application/atom+xml -H Slug:new-entry \ --data-binary @- -X POST "http://localhost:3000/mycollection"
Slugはヘッダで指定します.ここで指定したデータを実際に使うかどうかはサーバ実装に依存します.これに対して返ってくるxmlは以下のようになります.
<?xml version="1.0" encoding="utf-8"?> <entry xmlns="http://purl.org/atom/ns#"> <title>New Entry</title> <content mode="xml"> <div xmlns="http://www.w3.org/1999/xhtml">Content of my entry</div> </content> <app:edited xmlns:app="http://www.w3.org/2007/app">2008-02-11T20:00:12+09:00</app:edited> <modified>2008-02-11T20:00:12+09:00</modified> <id>http://localhost:3000/mycollection/new-entry.atom</id> <link xmlns="http://www.w3.org/2005/Atom" rel="edit" href="http://localhost:3000/mycollection/new-entry.atom"/> </entry>
この場合の"entry resource"はサーバに指定できています(mycollection/new-entry.atom).で今回の日記の最後がuploadしたデータの編集.うまく行っていません.たぶんやり方としては,
curl -s -H Content-Type:application/atom+xml --data-binary @- \ -X PUT "http://localhost:3000/mycollection/new-entry.atom"
というコマンドを使って
<?xml version="1.0" encoding="utf-8"?> <entry xmlns="http://www.w3.org/2005/Atom"> <content type="xhtml"> <div xmlns="http://www.w3.org/1999/xhtml">Content of my entry.</div> </content> <app:edited xmlns:app="http://www.w3.org/2007/app">2008-02-11T22:26:40+09:00</app:edited> <updated>2008-02-11T22:26:40+09:00</updated> <id>http://localhost:3000/mycollection/new-entry.atom</id> <link rel="edit" href="http://localhost:3000/mycollection/new-entry.atom"/> <title>New Entry ver.2</title> </entry>
というxmlを送ればいいようなんですが,なんでこのxmlを送ればいいのかがわかりません.追記:変更する箇所,この場合だとtitleタグの中身かcontentタグの中身を書き換えて送ればいいってことに,この日記を書いた後気がつきました.edited, updatedの中身はサーバが設定しているから,クライアント側で考えて時間を設定しなくてもよいみたい.
続く
たぶん…