JSONでデータを返すAPIは構造の意味を持たせつつArrayを返そう

すっげー初歩的な話。初歩的すぎて『Web API: The Good Parts』にもたぶん載ってない。

あと envelop の話はあえて無視してます。envelop を付けるべきか否かはこのエントリでは扱いません。あくまでデータの話に限定しています。

まとめ

自分でお手軽に作る時に key-value のデータをそのまま返しちゃう場合があるけど、これはやめた方がよい。

つい

{
  "key1": "val1",
  "key2": "val2",
  ..
}

こういうことしたくなる。楽だけどこれはやめた方がよい。

[
  {
    "key": "key1",
    "val": "val1",
  },
  {
    "key": "key2",
    "val": "val2"
  },
  ..
]

この方がよい。

例えば id と name を持つデータなら

{
  1234: "alice",
  2345: "bob"
}

ではなく

[
  {
    "id":   1234,
    "name": "alice"
  },
  {
    "id":   2345,
    "name": "bob"
  }
]

の方がよい。

理由1 - 順番が意図せず変わる

まず Object や Hash, Map などの構造をそのまま JSON に serialize する際に順番がどうなるか分からない。

本来順番に依存しない構造なのだから当たり前なのだが、例えば PHP の場合は

  • array は順番の維持される map のような何か
  • json_encode は key が数値だと array の順番を並べ直して encode する

というコンボが発生して、結果として json_encode する前と後で順番が変わってしまう。これでバグが生まれると割ときついですね。盲点。あくまで PHP の array や Ruby 1.9 以降の Hash がたまたま順番を維持してくれるだけという簡単な事実を忘れてはいけない。

で、これが大事なところなのだが、

本当に順番に依存しないかどうかはそのデータを serialize/deserialize する部分だけでは分からない。それは UI や他の DBMS などの「インターフェイス」の部分で何を期待するかで決まる。

だから本当は元のデータ構造の段階から順番に期待する処理は順番が確実に維持される構造にしておくべき。つまり

{}

ではなく

[
  {},
  {}
]

の方がよい。こうしておけばサーバ側とクライアント側で扱うデータ構造が変わってしまうことがないし、処理がブレることもない。

理由2 - なんの項目を扱っているのか分からない

ただし、上のように Ruby で言う Hash の Array みたいな構造にしただけではまだデータを扱いにくい。2項目しかないとつい

[
  {
    "key1": "val1"
  },
  {
    "key2": "val2"
  },
  ..
]

みたいにしたくなるが、これはデータを作るのも利用するのも同じコードの中ならまだいいけど、距離が離れると意味が分からなくなるのでやめた方がよい。

「この key はどういう意味なのか? value は何か?」がデータの中に存在しないし、だいたいの言語で key を取り出す方法も value を取り出す方法もない。1

で、結局 record[0], record[1] みたいなものをベタ書きすることになる。

これはつらいのでやめるべき。

理由3 - 変更に弱い

理由2 で挙げた「避けた方がよい形式」だが、項目が3つ以上になったらこの形式は通用しない。つまり何かあったら

  • データ構造をやや大きく変更せざるを得ない
  • データ構造が変わるとクライアント側のコードへの影響が大きい

だったら最初から全部同じ方法で扱うようにした方がよい。

  1. keys や values は取り出せるが、一つしかないのは分かっているのにいったん Array が手に入ってどんな構造を扱っているかも分かりにくくなる。 

Kanazawa.sysadmin を考えてみる

先週(1/17)、ぼそっと kanazawa.sysadmin と twitter に流したら良好な反応があったので、ちょっと遅くなってしまったけどアイディアを吐き出してみる。

対象

専門として、あるいはたまたまシステム管理的なことをやっている人

  • ホスティング企業勤務
  • いわゆる企業の情シス
  • いろいろなものを納入する業者(事務系でもセットアップやメンテくらいやるよね)
  • ショップの人
  • たまたま周りより詳しい学生
  • なんとなく興味ある人

てゆーか、システム管理ってなんだろう?1 風呂敷を広げてみたら自分もよく分かっていなかった感じ。

レベル不問。

内容

  • サーバ管理の困った/こんな工夫してます
  • クライアント管理の困った/こんな工夫してます
  • その他業務支援の困った/こんな工夫してます
  • デバイス、ネットワーク周りの困った/こんな工夫してます
  • こんなユーザー企業が好き/いやだ
  • こんな納入業者が好き/いやだ
  • sysadmin の自負/悲哀
  • ほか

たぶんまだまだあるんだと思うけど。

パターン

方法もいくつかあるような気がする。大きく分けるとこんな感じ?

  1. 洗い出し、ブレインストーミング(発散系)
  2. 調査、読書、ハック(絞り込み系)
  3. まとめ

いずれかを行ったり来たりするような感じになるんじゃないかな。

会場

恐らく小規模で地味にいくと思うので、金沢では

  • ITビジネスプラザ武蔵
  • 近江町交流プラザ
  • 勤労者プラザ

辺りの会議室を使わせてもらうのがお手軽でいいんじゃないかと思っている。

電源、ネットワーク周りの設備を考えるとITビジネスプラザ、そこにこだわらない、例えば本を基本にしたり持ち寄った資料でディスカッションをベースにするのであれば、近江町交流プラザや勤労者プラザの方がたぶん安くあがる。近江町は平日の遅い時間なら駐車場無料なのもポイント。

とりあえず第0回は

  • 内容はどれでもよい
  • 発散系で以下のように考えると合計 2.5h ちょっと短いか?
    • 中くらいのネタ ( 30m )
    • LT ( 15 ( + 5 ) x 3 )
    • アンカンファレンス的なディスカッション ( 1h )

人数次第なのでまずはどれだけ広報できるかと、「客寄せ」のネタが揃うかどうかがポイントかな。ある程度頭数が揃ったらディスカッションでいろいろ探れるんじゃないかと思う。

あるいは

  • 完全に kanazawa.js 方式にして各自が自由に自分のやりたいことをやる

という手もあるんだけど、js のようにキャッチーで明らかに需要のある分野でもないというか、分野が広すぎるのでさすがに躊躇してしまう。この方式で行けそうかどうかは第0回次第な気もする。

いつやる

時間が短くなりそうなら平日にやっちゃう手もあるんだけど、平日の勉強会って自分でも参加の可否が読みにくいので厳しいのかなぁ。あと遠方からの参加は難しくなるね、当然だけど。

でも週末は大きくて魅力的なイベントが多いのであえて外して平日の方が地味で良いかも? もうそろそろ勉強したい人はみんな時間埋まってきてるよね。週末は割と魅力的なイベントが多いし、家族サービス大事にしたい人はあまり週末の長い時間を割きたくないでしょう。

週末やるならあんまり短い時間はどうかなってちょっと思ってしまったりするんだけど、とりあえず第0回は週末の方が都合合わせやすいかな?

サイトどうしよう

kanazawa.js は facebook や tumblr を基本にしていてイマドキな感じ。ML が必要だとこの構成だけじゃアレだけど、必要ないならこんなんでもいいのか。どっちも自分はほとんど使ってないからよく分かってないけど、見せたい情報にフォーカスさせるのはこういう方法の方がやりやすいのかもしれない。

qwik.jp も使ってみたいと言えば使ってみたい。asakusa.rb リスペクトというか。ただ、未だに何ができるのか自分でもよく分かっていない。

Google Groups はイマイチな気がする。ML しか考えてないならいいけど、ページの記述やらなんやらがどーにも。あんまりやる気ないみたいだし。

github + github pages ってのは技術的に面白そうだけど、テキスト情報以外はあんまりお手軽じゃないよね。うーん。まぁそれも sysadmin ぽいと言えばぽいけど。

  1. 自分の中では「何でも屋」の一言で片付けちゃってるけど。 

Emacs 21 でも C-x RET r したい

今日やったのはこんな感じ。

09:34:32 wtnabe< emacs 21 でも C-x RET r で revert-buffer を呼び出した
い
09:59:25 wtnabe< (global-set-key (kbd "C-x RET r") 'revert-buffer) か。
ぼくにもできたよ! さんきゅー @odz !
10:00:09 wtnabe< kbd 関数を使うのはめちゃめちゃ読みやすくてよいなぁ。

cf. キーバインドの指定方法 - odz buffer

正確には 22 の C-x RET r とまったく同じ動きではないんだけど、それは仕方ない。

cron, crontab, and more

※ タイトルには意味ないです。

Unix の伝統的なツールで、かつ GNU のツールが(普及|台頭)していないものには意外と細かいバージョンの違いがある。cron もその一つ。

自分で見て試した限りでは以下のような違いがあった。

FreeBSD/etc/cron.d/* を読まない
Linuxcron -j でジョブの実行を数秒分散させるってことはできない?

実行時間の分散についてはランダムにずらすよりは fcron や uschedule の方が賢いのでそんなに気にする必要はないだろうけど、FreeBSD の「設定ファイルを分けることができない」っていうのは、設定するものが増えてくると面倒なような気がしないでもない1

で、それとは別に cron て意外と不便だなと思うのは

  1. 秒単位の指定はできない
    • やるとしたらプログラムを指定秒 sleep してから動くようにセットする
  2. 「第2月曜」という指定はできない
    • やるとしたら月曜日に実行を予約して、立ち上げたプログラムの方で第2に当たるかどうかをチェックしないといけない

辺り。この辺は Windows のタスクスケジューラの方がよくできている。2

特に 2 のような要求はビジネスでスケジューリングしたいときには結構出てくると思う。毎月の最終営業日が終業したタイミングでバッチ処理を走らせる、なんてのはいかにもありそうだ3。その辺考えると伝統的な cron に代わるスケジューラってあってもよさそう。ということでもう一度調べたらこんなものを見つけた。

  • Mcron - GNU Project - Free Software Foundation (FSF)
    • Guile で書く
  • Fcron : a periodical command scheduler for Unix and Linux systems
    • load average とか気にしてくれます。ほとんど cron 互換と言っても差し支えないような?
    • 24時間動いてなくてもいいらしい。その機能は結構嬉しい。開発用クライアントマシンで daemon のログがものすごいことになったりするのをうまく解決できるかも。あんまり細かく見てないけど。
  • uschedule
    • もうちょっと細かい指定ができるんだけど、互換性もなくなってきてるし、なんでこんなにいっぱい分かれてるんだろ?

load average を見て実行を遅らせるとか、やっぱシステム寄りの見方が中心なのかなぁという感じがする。

OSX は launchd で iCal との連携も強化してるっぽいけど、ぱっと見た感じ XML を使うみたいで、直書きのことは考慮してないかなぁ? まぁ人間に都合のいい細かい情報って、逆に機械に読みやすい形式で書式を決めていくのが面倒なケースも多いのでしょうがないのかもしんない。

つーことで結局のところ mcron のようなアプローチで、自分の書きやすい言語で日時などの条件をチェックしてから目的のプログラムを動かす、っていう流れにしちゃうのがいちばんいいのかもしんない。一瞬、YAML で設定ファイルを〜とか思ったけど、そういうことはしない方がたぶんいい。その方法で簡単に記述できるような条件なら、妥協も組み合わせて既存の crontab のフォーマットで再現すべきだろう。

ブツは cron ジョブに複雑な条件を与えやすくする の方に載せました。

  1. 分かれてる方が面倒なケースもあるし、一概には言えないけど。 

  2. タスクスケジューラが設定一覧をファイルに簡単に吐き出せるとか、逆にファイルからサクっと設定を読み込めるとか、そういうことができれば使いやすいのになぁ。 

  3. この場合は日付でも指定できないし、曜日でも指定できない。毎月1日の前日の夜、という指定で置き換えるなら条件的にはもう少し楽になるけど。 

へー openCASL か

※ スラドの記事はなんでちゃんとリンク用意してないんだ。

書きたかったのはこれだけ。

「昔、CASIO のポケコンで CASL 勉強しました。」

結局 FORTRAN で受験したんですが。当時はまだ問題に英語とか数学とか存在していたので、勉強する内容がその分減って助かりました。(二種と呼ばれていましたが何か問題でも?)

今はセキュアプログラミングの問題を Perl で回答できるのですよ。何とも言えないけど変に「すごい」感じがするのはなんでだろ。まぁ試験と現実が近くなっていくのはいいこと、なのかな?

写真整理続き

OS X 版 XnView が案外使いにくい。Windows では ViX か XnView を使っていて、まだ XnView への習熟があまり進んでいないというのもあるかもしれないけど、なんか Windows 版とできることに結構違いがあるような。画像を回転して保存し直すのもうまくいかないし。うーむ。

枚数が少ないのでとりあえずプレビューで。iPhoto を使わないのは無駄に重たいから。OS X に乗り換えてからそういえばあまり画像の整理してないな。もう少し習熟せんといかん。やっぱ GraphicConverter が王道なのかなぁ。

勉強になりました

OOエンジニアの輪! 〜 第 25 回 結城浩さんの巻 〜

なんとなく思っていたことがはっきりと言葉になっている部分があって、少しすっきりしました。

若すぎるときには分からなかったことでもあります。時間は偉大ですな。

結局 Win98 サポートって

パンピーにとっては延長とは言えないんですね。

有償サポートのユーザー以外は「現状の Windows Update 適用済みの状態に回復できる期限が延びた」というだけで新しいパッチがリリースされるわけではないと。パッチを個別に落として CD に焼くなど、サポート期限切れに備えていた人にとってはまったく何も変わらないわけです。(まーわたしゃそんなマメなことはしてませんが。)

フライング情報を追いかけてたら混乱してしまったんだけど、まぁ要するに予定通り Win98 には退場していただくということですな。せめて Service Pack を用意してくれると嬉しいんだけどなぁ。。。

Emacs で半角カナが出せない

困ったなぁ。

rxvt-j@cygwin 経由 Linux の上の Emacs で半角カナの表示ができない。XEmacs ならイケるんだけど、設定があれこれ違うので XEmacs には 乗り換えたくないし、色分けが地味すぎてもろもろの作業をするにはちと困る。

EUC-JP のファイルに半角カナが入っているとコードの判別に失敗しているのか、多バイト文字が全然表示できない。仕方ないので Samba でマウントして xyzzy で編集するんだけど、なんだかどうも釈然としない。xyzzy はきらいじゃなけど、コンソール上で完結させたい場合もあるわけで。

うーん、まだまだ使いこなせてないぜ。

のっぺ

http://www.yomiuri.co.jp/e-japan/syoku2003/index.htm

実家ののっぺとはずいぶん違うな(^^;

About

例によって個人のなんちゃらです

Recent Posts

Categories

Tool 日々 Web Biz Net Apple MS ことば News Unix howto Food PHP Movie Edu Community Book Security Text TV Perl Ruby Music Pdoc 生き方 RDoc ViewCVS CVS Rsync Disk Mail FreeBSD Cygwin PDF Photo Zebedee Debian OSX Comic Cron Sysadmin Font Analog iCal Sunbird DNS Linux Wiki Emacs Thunderbird Sitecopy Terminal Drawing tDiary AppleScript Life Money Omni PukiWiki Xen XREA Zsh Screen CASL Firefox Fink zsh haXe Ecmascript PATH_INFO SQLite PEAR Lighttpd FastCGI Subversion au prototype.js jsUnit Apache Trac Template Java Rhino Mochikit Feed Bloglines CSS del.icio.us SBS qwikWeb gettext Ajax JSDoc Rails HTML CHM EPWING NDTP EB IE CLI ck ThinkPad Toy WSH RFC readline rlwrap ImageMagick epeg Frenzy sysprep Ubuntu MeCab DTP ERD DBMS eclipse Eclipse Awk RD Diigo XAMPP RubyGems PHPDoc iCab DOM YAML Camino Geekmonkey w3m Scheme Gauche Lisp JSAN Google VMware DSL SLAX Safari Markdown Textile IRC Jabber Fastladder MacPorts LLSpirit CPAN Mozilla Twitter OpenFL Rswatch ITS NTP GUI Pragger Yapra XML Mobile Git Study JSON VirtualBox Samba Pear Growl Mercurial Rack Capistrano Rake Win RSS Mechanize Sitemaps Android JavaScript Python RTM OOo iPod Yahoo Unicode Github iTunes God SBM friendfeed Friendfeed HokuUn Sinatra TDD Test Project Evernote iPad Geohash Location Map Search Simplenote Image WebKit RSpec Phone CSV WiMAX USB Chrome RubyKaigi RubyKaigi2011 Space CoffeeScript Nokogiri Hpricot Rubygems jQuery Node GTD CI UX Design VCS Kanazawa.rb Kindle Amazon Agile Vagrant Chef Windows Composer Dotenv PaaS Itamae SaaS Docker Swagger Grape WebAPI Microservices OmniAuth HTTP 分析基盤 CDN Terraform IaaS HCL Webpack Vue.js BigQuery Middleman CMS AWS PNG Laravel Selenium OAuth OpenAPI GitHub UML GCP TypeScript SQL Hanami Document SVG AsciiDoc Pandoc DocBook Develop Jekyll macOS Node.js Vite Heroku Transformer AI Data Cloud Wasm