REST

REST


概要

LiftでRESTを使うためには、

  • RestHelperトレイトを継承したobjectを作成
   import net.liftweb.http.rest._
   object MyRest extends RestHelper 

  • RestHelperのserveメソッドを呼び出す
serveメソッドは、PartialFunction[Req, ()=>Box[JsonResponse]]を引数にとる。
つまり、Reqインスタンスがcaseに渡されて、caseの中では、引数なしの関数を返さなければならない。
さらに、その関数は、Boxで包んだJsonRequestを返さなければならない。
   import net.liftweb.http.rest._
   object MyRest extends RestHelper {
     serve {
       case "api" :: "static" :: _ JsonGet _ => JString("Static")
     }
   }

  • Boot.scalaでLiftRulesに追加
いくつでもでも追加できる。
LiftRules.dispatch.append(MyRest)


  • 注意
serve関数の中でいくつもパターン分けをしていると、コンパイル時にエラーを出す。
この場合は、server関数をもう別に呼び出すことで回避できる。
   object MyRest extends RestHelper {
     serve {
       case "api" :: "static" :: _ JsonGet _ => JString("Static")
          ....
     }

     serve {
       case "api" :: "static" :: _ JsonGet _ => JString("Static")
          ....
     }
   }

POSTリクエスト

  • lift側
object MyRest extends RestHelper {
  serve {
    case req @ Req("api" :: "static" :: "test" :: Nil, "json", PostRequest) => {
      val body = new String(req.body.open_!)
     ....
    }
  }
}
  • javascript側
(function() {

 req = new XMLHttpRequest();
 req.open("POST", "http://localhost:8080/api/test.json", true);
 req.onreadystatechange = function() {
   if(req.readyState == 4) {
     if(req.status == 200) console.log(JSON.parse(req.responseText));
     else console.log("error");
   } 
 };

 req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 
 req.send(JSON.stringify({
   key1:"value1"
 }));

})();


クロスドメインREST


XMLHttpRequestは、通常同じドメインにしかリクエストが投げられないが、
サーバ側の設定でリクエストを投げることができる。

レスポンスヘッダに以下の項目を追加する。
     	("Access-Control-Allow-Origin", "*")
     	("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
     	("Access-Control-Allow-Headers", "Content-Type")

Access-Control-Allow-Methodsは、必要であれば、PUTやDELETEなども追加する。
POSTメソッドの場合は、OPTIONSメソッドも必要。

常にヘッダに追加しておきたい場合は、以下のように書くと便利かも。
jsonRestは、serveのように扱う。

 import net.liftweb._
 import http._
 import rest._
 import json._
 import js._
 import js.JE._
 import common._

 object Rest extends RestHelper {

   jsonRest {
     case ("sample" :: "api" :: "get" :: Nil, GetRequest ) => {
          ....
     }
     case ("sample" :: "api" :: "post" :: Nil, PostRequest ) => {
          ....
     }
   }
   
   def jsonRest( pf: PartialFunction[(List[String], RequestType), JValue] ) = serve { 
     case req if pf.isDefinedAt( (req.path.partPath, req.requestType) ) => () => Full(JsonResponse(
pf( (req.path.partPath, req.requestType) ),
    	("Access-Control-Allow-Origin", "*") :: 
    	("Access-Control-Allow-Methods", "GET, POST, OPTIONS") :: 
    	("Access-Control-Allow-Headers", "Content-Type") ::
    	Nil,
    	Nil,
    	200
     ))
   }
   
 }
最終更新:2012年01月31日 21:00