2012年8月28日火曜日

lift-jsonのextractで痒いところに手を伸ばす

lift-json便利ですね。Play2に組み込まれてるJsonも「型クラスかっけー」って感じで好きですけど、Playを使わないところではやっぱりlift-jsonがデファクトっぽい感じになってるかなーと思います。
で、lift-jsonでJsonからモデルにマッピングするにはどうするのかなーと思って検索してみると、大抵こちらに行き着きます。

Lift Json の case class への変換がとても便利な件 | scalaとか・・・

これ、すっげー便利なんですけど、実際に使ってみると、そのままじゃうまくいかない場面が出てくるんですよ。
なので、今回は「うまくいかない場面」 = 「痒いところ」に手を伸ばしてみます。

うまくいかない場面1: case objectへのマッピング


例えばこんな風に、Javaでいう列挙型みたいなモデルを作った場合。



で、この3つにそれぞれ0,1,2が割り当てられていて、Jsonでは例えば
{ carrier: 0 }
といった表現がされているとします。

この場合は、この型に変換する機構をlift-jsonは持っていないので、作ってやる必要があります。



このようにSerializerを作っておくと、Formatsに組み込むことができるので、以下のように自作Serializerを組み込んだ新しいFormatsを使ってextractできます。





うまくいかない場面2: Jsonの構造がちょっと違う


例:楽天ウェブサービスの市場商品検索2

これ、返りのJsonが以下のような構造をしています

{
  xxx: yyy
  ...
  Items: [
    {
      Item: {
      }
    },
    {
      Item: {
      }
    }
  ]
}

なぜかItemsとItemだけ頭文字が大文字なのかとか、ItemsのArrayの中身がItemそのものではなく、Itemというフィールドを持ったオブジェクトなのかとかツッコミたい感じです。ツッコミたいだけならいいんですけど、デフォルトのextract一発変換に頼ろうと思うとこういうのが結構ネックになるんですよね。
これ、「うまくいかない場面1」と同じようにSerializerを作っちゃってもいいんですけど、他にもたくさんの要素を含んでいて、ほんの一部だけを修正するためにSerializerを作るのはめんどうです。なので、こういう場合はJsonAST側を都合の良いようにいじっちゃった方が早いです。

変換にはtransformを使います。こいつ、再帰的にJsonASTを操作してくれるので、簡単にASTをいじれます。
詳しくはlift-jsonのソース見ちゃったほうが早いです。



こんな感じ。

0 件のコメント:

コメントを投稿