2017-02-12 18 views
0

Давайте предположим, что следующий код:Akka HTTP (не) маршалом черты

sealed trait Action { 
    def run(): Boolean 
} 

case class SimpleAction(parameter: String) extends Actions { 
// some impl 
} 

case class ExtendedAction(parameter1: String, parameter2: String) extends Actions { 
// some impl 
} 

Теперь я хочу, чтобы определить, где один WebService можно извлечь действия. Как я могу маршаллировать действие, так как это просто черта и какой-то конкретный тип?

Я нашел это https://github.com/spray/spray-json#providing-jsonformats-for-other-types в Документах. Есть ли более простой способ достичь этого, чем использовать этот подход, смешанный с сопоставлением с образцом?

ответ

1
import spray.json._ 
import DefaultJsonProtocol._ 

implicit val simpleActionFormat = jsonFormat1(SimpleAction) 
implicit val extendedActionFormat = jsonFormat2(ExtendedAction) 
implicit val actionFormat1 = new JsonFormat[Action] { 
    override def write(obj: Action): JsValue = obj match { 
    case a: SimpleAction => JsObject("type" -> "simple".toJson, "value" -> a.toJson) 
    case b: ExtendedAction => JsObject("type" -> "extended".toJson, "value" -> b.toJson) 
    } 

    override def read(json: JsValue): Action = json.asJsObject.getFields("type", "value") match { 
    case Seq(JsString("simple"), js) => js.convertTo[SimpleAction] 
    case Seq(JsString("extended"), js) => js.convertTo[ExtendedAction] 
    case _ => throw new RuntimeException(s"Invalid json format: $json") 
    } 
} 

Или, если вы заботитесь только о преобразовании Actions в JSON, а затем просто:

implicit val simpleActionFormat = jsonFormat1(SimpleAction) 
implicit val extendedActionFormat = jsonFormat2(ExtendedAction) 
implicit val actionFormat = lift(new JsonWriter[Action] { 
    override def write(obj: Action): JsValue = obj match { 
    case a: SimpleAction => a.toJson 
    case b: ExtendedAction => b.toJson 
    } 
})