isyumi_netブログ

isyumi_netがプログラミングのこととかを書くブログ

RESTful APIのエンドポイントを綺麗に設計しよう

ブラウザやスマホアプリがサーバーとデータをやり取りする際にHTTPが使われることが多い。今回はそのURLの話だ。まずなんでこの話をするかを聞いてほしい。

 

あなたが参加しているシステムのサーバーとクライアントのやり取りは全部で何種類あるだろうか?

  • ユーザー登録
  • 投稿検索
  • 書き込み

等々。きっと数十種類以上はあると思う。HTTPを使う場合これら一つ一つの機能にURLを割り振らなければいけない。

ちなみにhttps://example.com/users?age=20 というURLの中でhttps://の部分をスキーマといいexample.comをホスト、/usersをパス、age=20をパラメータという。機能の割り振りに使えるのはパスの部分だ。何十個もある機能に統一感のある割り振りをしたい。そのために、どんな基準を使えばいいか。

メンタルモデルという言葉を知っているだろうか。物と物がどう作用するかについてのイメージだ。

例えば、車のウィンカーだ。ウィンカーは上に持ち上げれば左が点滅し、下に下げれば右が点滅する。あなたはどうやってこのルールを覚えているか。きっと「これからハンドルを回す向きに動かす」と覚えているはずだ。ではもし将来車が空を飛ぶようになり、上下にもウィンカーを出さなけれが行けなくなったとき、レバーをどっちに倒すべきかあなたは迷ったりしないだろう。これがメンタルモデルだ。本当はこれからハンドルをどちらに回すかとウィンカーの向きには何の関係もないのにそう考えるとわかりやすい。

プログラマーにとって良い実装をすることと同じくらい良いメンタルモデルを設計することは大事な仕事だ。URLを見れば即座にそのAPIがどんな機能を持っているのか想像がつき、将来こんな機能を増やしたいならどんなURLにするか判断に困らないようなメンタルモデルを設計するべきだ。

実践すべきことはこちらのQiitaに全部書いてある。細かいところで議論になっているが大筋この通りにすればいい。あとで読んでほしい。

 

qiita.com

では、どういうメンタルモデルでこれを考えればいいだろうか。これから作るシステムは1枚のJSONに全て管理されているというメンタルモデルで考えてほしい。そのJSONにはすべての情報が書き込まれている。またそのJSONを書き換えると世界はその通りに変化する。そこでクライアント側は望む機能を実行するにはサーバーに保存されているそのJSONの箇所を指定して読み込んだり書き込んだり削除したりすればいいとわかる。RESTful APIのパスはJSONの場所指定と一致する。

だからあなたの仕事はシステムの状態を全て表現したJSONのフォーマットを考えることだ。例えば掲示板ならこんなJSONになりそうだ。

{

  "users" : [

    {"userID": "111", "name" : "たろう"},

    {"userID": "222", "name" : "じろう"}

  ],

  "messages" : [

    {"userID" : "111", "message" : "こんにちは"},

    {"userID" : "222", "message" : "はじめまして"}

  ]

}

 

ということは投稿を全部取得するAPIは/messagesで、名前編集APIはPUT /users/rename ではなくPUT /users/111/name だとわかるだろう。

このように、システムの状態を1枚のJSONで考えれば、必然的にきれいな設計になる。