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")
}
}
いくつでもでも追加できる。
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リクエスト
object MyRest extends RestHelper {
serve {
case req @ Req("api" :: "static" :: "test" :: Nil, "json", PostRequest) => {
val body = new String(req.body.open_!)
....
}
}
}
(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