跟所有Lift的feature一样,支持REST也是非常非常得简单。
Mixin这个trait:
Boot.scala里面加上:
1 | LiftRules.dispatch.append(AdminAPI) |
如果不需要创建session(不创建著名的S对象),还可以:
1 | LiftRules.statelessDispatchTable.append(AdminAPI) |
然后就是URL匹配:
以上都是GET的JSON接口。JsonGet会检查HTTP头里面的Accept以确认client是否支持JSON,这里需要注意的是“*/*”表示所有都接受(这个应该已经在2.3里面被修复掉了);当然如果Accept里面不支持JSON,JsonGet还会去查询URL是否是.json结尾。
具体解释一下上面的例子。
对于URL为 http://server/api/add.json 的请求,第一条匹配规则命中,最后那个“_”是Req,然后调用add方法,add的返回值需要是LiftResponse类型;其实LiftReponse是个啥都不干的trait,有很多实现,JsonResponse、XmlResponse等等,总之几乎不用特别在意,Lift里面能作为response返回给client的都能用。
其他的匹配类似处理。
给个add方法的实现:
1 2 3 4 5 6 7 8 9 10 11 12 | private def add = { val linkId = param(ShortenedUrl.originUrl.name).map(x => { shortenedUrl.find(ShortenedUrl.originUrl.name -> x).map(_.linkId.value) or { val tmp = (DependencyFactory.inject[NextIdGenerator].open_! !? 'id).toString shortenedUrl.createRecord.linkId(tmp).originUrl(x).shortUrl(Props.get(Site).open_! + "/" + tmp).date(new Date). ip(containerRequest.map(_.remoteAddress).toString).clickCount(0).save Full(tmp) } }) (StatusField -> linkId.map(_.map(x => SuccessStatus)).openOr(Full(FailedStatus)).openOr(FailedStatus)) ~ (ShortenedUrl.linkId.name -> linkId.openOr(Full("")).openOr("")) } |
返回一个JSON对象{status: “successful”, linkId: “1″}。
Lift利用Scala对DSL的支持把JSON整得很舒服,几乎跟js原生的用起来没区别:
1 2 3 | ("name" -> "honnix") ~ ("address" -> "somewhere") ~ ("phone" -> List("111", "222", "333")) |
等价于:
1 2 3 | {name: "honnix", address: "somewhere", phone: ["111", "222", "333"]} |
具爽吧?