2016-10-12 4 views
0

私はScalaとPlayを使用してマイクロサービスを構築しましたが、以前のバージョンのサービスと同じデータを返す新しいバージョンのサービスを作成する必要があります。異なるJSON形式。このサービスは現在、暗黙の書き込みコンバータを使用してこれを行います。私のコントローラはMyJsonWritesに暗黙の定義が含まれているようなものです。JSON Writing Converter for Playコントローラアクション

class MyController extends Controller with MyJsonWrites { 
    def myAction(query: String) = Action.async { 
     getData(query).map { 
     results => 
      Ok(Json.toJson(results)) 
     } 
    } 
} 

trait MyJsonWrites { 
    implicit val writes1: Writes[SomeDataType] 
    implicit val writes2: Writes[SomeOtherDataType] 
    ... 
} 

JSONのフォーマットが異なるmyActionの新しいバージョンが必要です。私が最初に試みたのは、MyControllerを基本クラスにして、暗黙の値を持つ独自の特性でサブクラスを拡張することでした。このようなもの。

class MyNewContoller extends MyController with MyNewJsonWrites 

MyNewJsonWritesに定義された暗黙の値は、スーパークラスのメソッドでは使用できませんので、これはしかし、動作しません。

MyNewJsonWritesで定義されているコンバーターを何らかの形で使用していたコントローラーに新しいアクションを作成するだけの方が理想的です。確かに、私はオブジェクトの特性を変更し、各メソッドで暗黙の値をインポートすることができますが、私はJson.toJsonを呼び出すときimplicitsが範囲内にあるようにmyActionのメソッド本体を複製する必要があります。あまりにも多くのものがあるので、暗黙的なパラメータとしてそれらを基本メソッドに渡したくありません。私は実際にインポートとJson.toJson呼び出しを行う基本メソッドにパラメータとしてメソッドを渡すことができたと思います。このようなもの。私はちょうどもっと良い方法があると思った。

def myBaseAction(query: String, toJson: Seq[MyResultType] => JsValue) = Action.async { 
     getData(query).map { 
     results => 
      Ok(Json.toJson(results)) 
     } 
    } 

def myActionV1(query: String) = { 
    def toJson(results: Seq[MyResultType]) = { 
     import MyJsonWritesV2._ 
     Json.toJson(results) 
    } 
    myBaseAction(query, toJson) 
} 

答えて

1

代わりのScalaの暗黙の解像度に依存する、あなたが直接あなたの書き込みを呼び出すことができます。

def myBaseAction(query: String, writes: Writes[MyResultType]) = Action.async { 
    getData(query).map { results => 
    val seqWrites: Writes[Seq[MyResultType]] = Writes.seq(writes) 
    Ok(seqWrites.writes(results)) 
    } 
} 

def myActionV1(query: String) = myBaseAction(query, MyJsonWritesV1) 
def myActionV2(query: String) = myBaseAction(query, MyJsonWritesV2) 
+0

私も明白について考えていませんでした。ありがとう! –