Slim3でhttpメソッドとControllerをマッピングする
前回、Slim3における拡張子付きURIのマッピングを試した。
今度は、同じURLへのリクエストについて、httpメソッドがGETならGetController、DELETEメソッドならDeleteControllerが呼ばれるみたいな感じで、httpメソッドとControllerを一対一にしたら、RESTfulなコードを書くときにController#isGet()とかを使うよりすっきりするんじゃないかと思い、試した。
まず、addRoutingは以下のようにする。Controller名にひもづく部分は適当に"httpmethod"とかにする。置換用文字列。
public AppRouter() { addRouting("/user/{id}", "/user/httpmethod?id={id}"); }
Controllerに処理が移る前に、requestのメソッドを取得する必要がある。RouterImpl#route()の引数がrequestなので、これをAppRouter内でオーバーライドして、マッピングのtoをrequestから取得したhttpメソッドの文字列で書き換える。
@Override public String route(HttpServletRequest request, String path) { String to = super.route(request, path); if(to != null) { return to.replace("httpmethod", request.getMethod().toLowerCase()); } return null; }
ここではControllerのクラス名をGet〜とかPost〜にした。よって"GET"とか"POST"だとマッピングされないので、toLowerCase()で小文字にする。
上記AppRouterを記述した上で、実際に試してみる。フォームからpostメソッドでURLにリクエストを投げるHTMLを用意。
<form action="./user/12345" method="POST"> <input type="submit" /> </form>
マッピングされるController。
public class PostController extends Controller { @Override protected Navigation run() throws Exception { response.getWriter().println("postcontroller"); response.flushBuffer(); return null; } }
これでプロジェクトをRunして、HTMLでSubmit。
マッピング成功。「/user/12345」というURLにPOSTメソッドで、root.controller.user.PostControllerが呼び出せた。
しかし、AppRouter#route()をオーバーライドしてるので、予期しない動作がありそうで怖い。あくまでも実験なので実用に耐えるかは未検証です。