Scala + Lift + REST — Возврат массивов с serveJx

У меня есть класс, который расширяет RestHelper для обслуживания элементов как в xml, так и в json. В настоящее время я реализую метод "serve" для возврата объектов в xml:

object Rest  extends RestHelper {

serve {

    case "supplier" :: "findAll" :: _ XmlGet _
        => supplierListToXml(Supplier.findAll)

}

def supplierListToXml(suppliers : List[Supplier]) = {
    <suppliers>{suppliers.mapConserve(f=> f.toXml)}</suppliers>
}

}

Я хочу обслуживать те же элементы, что и json, в зависимости от заголовка Accept, используя метод serveJx (объясненный в http://www.assembla.com/wiki/show/liftweb/REST_Web_Services).

Класс Supplier реализует Convertable, и я реализовал метод преобразования в классе Rest:

object RestApi extends RestHelper {
implicit def cvt: JxCvtPF[Convertable] = {
   case (JsonSelect, c, _) => c.toJson
   case (XmlSelect, c, _) => c.toXml
 }

serveJx {
    case Get("2.0" :: "supplier" :: "head" :: _,_)
        => Full(Supplier.findAll.head)
}

}

... и это работает, когда я обслуживаю одного поставщика. Но когда я хочу вернуть список поставщиков (List[Supplier]), метод преобразования не может быть применен.

    case Get("2.0" :: "supplier" :: "findAll" :: _,_)
        => Full(Supplier.findAll.toList)

... и я получаю ошибку компиляции:

"не удалось найти неявное значение параметра cvt:com.mycompany.api.RestApi.JxCvtPF[ScalaObject]"

Может ли кто-нибудь дать мне пример того, как изменить метод cvt, чтобы иметь возможность конвертировать список конвертируемых в LiftResponse?

Ваше здоровье! /Дж


person Julian    schedule 17.03.2011    source источник


Ответы (1)


Я нашел решение cvt-методом. Измените тип на неявный def cvt: JxCvtPF[Any], чтобы иметь возможность сопоставлять определенные классы. Затем реализуйте список конвертируемых как таковой:

//Generic list templates
    case (JsonSelect, c : List[Convertable], _) => JArray(for{item <- c} yield item.toJson)
    case (XmlSelect, c : List[Convertable], _) => <list>{c.mapConserve(f => f.toXml)}</list>

Полное решение:

object Rest  extends RestHelper {
implicit def cvt: JxCvtPF[Any] = {

    //Generic list templates
    case (JsonSelect, c : List[Convertable], _) => JArray(for{item <- c} yield item.toJson)
    case (XmlSelect, c : List[Convertable], _) => <list>{c.mapConserve(f => f.toXml)}</list>

    //Single-items of convertable
    case (JsonSelect, c : Convertable, _) => c.toJson
    case (XmlSelect, c : Convertable, _) => c.toXml
}
serveJx {

    case "supplier" :: "findAll" :: _ Get _
        => Full(Supplier.findAll)

    case "channelPackage" :: "findAll" :: _ Get _
        => Full(ChannelPackage.findAll)

    case "channelPackage" :: "findFromSupplierId" :: supplierId :: _ Get _
        => Full(Supplier.find(supplierId).head.channelPackages)

    case "device" :: "findAll" :: _ Get _
        => Full(Device.findAll)

    case "device" :: "findFromSupplierId" :: supplierId :: _ Get _
        => Full(Supplier.find(supplierId).head.devices)
}

}

person Julian    schedule 17.03.2011