29
30

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ASP.NETAdvent Calendar 2014

Day 20

ちゃんとRESTでつくるWebAPI

Posted at

切ない思い出

少し前だけれど、ASP.NET Web APIを使って開発をした。
開発要件からすると大変いい感じにフレームワーク選定したと思うし、急に決めた割には、今思っても良かったと思う選択だった。

ただいざクライアントに提供する機能を作ってるうちに、なんか変なことになってきた。

とりあえずPOST

クライアントからDBに対して読み書きしたい用事があるときは当然Webサーバーで、ASP.NET Web APIで作った機能を経由することにした。ただその時に、DBのテーブル(単体)に対するCRUDだったらテーブルからScaffoldした処理を使い、そうじゃない複数のテーブルがからむ処理は、基本POSTにしてそれぞれクラスを作って処理することにした。

今思うとなんでそんなことしたのかと思うが、System.Net.Http.HttpClientを使って通信する場合に、POSTにしておけばどんなオブジェクト渡しても同じようにシリアライズして送信してくれるからいいよね、という発想だったと思う。
確かに検索っぽい処理(何らかの情報を元に、何らかの情報を取ってくる)のときに、単純に特定のテーブルの属性値を渡すのではなくて、クライアント側が使っているオブジェクトをそのままシリアライズして渡してしまえば楽であろうという局面もあった。

結果的に、POSTメソッドだけ実行したコントローラーがたくさんできて、それぞれのコントローラーにはRPCで呼ばれる的な名前がついた。

これは例えば、

  • 利用者
  • 貸出リスト(本・利用者の中間テーブル)

kobito.1418700964.699912.png

みたいな構成のテーブルがあって、特定のユーザーの貸出情報を取得するときに、URIが
POST http://hostname/get_lendinguser
になっていて、BODYにuser_idが入っているみたいな感じだ。

やってしまうパターン

ASP.NET WebAPIにかぎらず、scaffoldの機能があるフレームワークは多い。
それでとりあえずチュートリアルとか見ながら作っていくと、だいたいテーブルがDBにあって、それに応じてModelとControllerとまあViewも生成されますみたいなことになる。
それでRESTのインターフェースもできているので、ああなるほどCRUDできますねみたいに覚えるのだけれども。

実際には、当然なにかリクエストがあったときに複数のテーブルを結合した結果を返したり、複数のテーブルで更新したりする。
そうするとその操作対象が何かということよりも、だんだんどんな操作をするのかというほうに頭が行き、結局APIとしてはよくわからないようになってしまったんであろう。

リソース。

とにかくRESTで重要なのは、サービスとしてアクセスできる対象をリソース(もの)でとらえることだ。
だから、アクセスするときにつかう表現に動詞っぽいものが入ってきたらそれはほぼほぼおかしい。

名詞でコントローラー名がついて、それに対してHTTPメソッドによって操作内容がかわるというかたちになるようにする。

名詞の選び方

といってもテーブル名そのままなら名詞化っていうのは簡単なわけだが、例えば複数テーブルをJoinした結果に対してどのような名前をつけるか。

きれいに行く形というのはその複数のテーブル(物理レベル)が表現しているデータの概念の方(概念レベル)の名前にする場合と思われる。

例えば、さっきと同じく

  • 利用者
  • 貸出リスト(本・利用者の中間テーブル)

kobito.1418700964.699912.png
みたいな構成のテーブルがあって、特定のユーザーの貸出情報を取得するようにすると、URIは
GET http://hostname/lendinguser/{user_id}
にする。

別にテーブルを物理レベルで見ると貸出中のユーザーなんてないんだけれども、クライアントからみた概念としては自然に見える。もちろん貸出が発生したら、同じURIでPOSTするということも自然に想定できる。

利点

RESTfulなインターフェースにしておく利点として、単純にAPIとしてわかりやすいということもあるだろうけれど、例えばRPC的に毎度サーバー側に処理を実装しなくても、2,3回リクエストすれば処理が完了できるようなケースでサーバー側の処理の負担が減る良さがあると思う。

クライアント・サーバー構成のシステムでサーバーがWebAPIで機能を公開するようなときは、サーバー側でインターフェースを公開するときにクライアント側もどんなインターフェースになるか調整しないといけないから、負担はお互いそれなりにかかる。
サーバー側で用意されているものを使うだけでやれるなら、クライアントがの実装としても楽になる。

例外

ちなみに、本当にクライアントからサーバー側の処理を呼びたいだけのときというのは、RPC的にインターフェースを作っても誰も文句は言わない。

コントローラーを増やすときの心構え

コントローラーを増やすときなので、以下のことに気をつける。

  • クラス名は「概念を表す名詞」をつける。

このあたりは、概念としてデータを捉えられていないととっさに変な命名をしがちなので、普段から整理することも大事だと思う。

29
30
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
29
30

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?