我使用Argonaut從遠程JSON提供者分析對象。該API有兩種類型的端點,一種是URL上的傳統REST請求以及單個JSON對象的響應。我能夠在這種類型的端點上輕鬆地使用Argonaut解析複雜的JSON返回對象。用Argonaut解析JSON流
我的問題是提供者的流式端點,它從給定端點的有界JSON對象集返回隨機JSON對象。這些對象按照它們在網站上出現的順序返回,並且可以隨時返回大約二十個不同對象中的任何一個。
通過API工作,我找不到使用Argonaut來處理這個問題的方法。這些API似乎都需要類型參數化,這在下一個對象的類型無法預測的環境中很難實現。一種選擇是根據每個JSON塊中的前幾個字符分派到不同的編解碼器,但這會破壞將JSON字符串發送到解析器並獲取對象的目標。
我已經能夠迄今爲止找到的最好的是讓所有的頂級case類的擴展空trait
:
implicit def ModelDecodeJson: DecodeJson[Model] =
DecodeJson(c =>
c.as[ModelSubclassA].asInstanceOf[DecodeResult[Model]]
||| c.as[ModelSubclassB].asInstanceOf[DecodeResult[Model]]
// many more here!
)
不幸的是,ModelSubclassA
和ModelSubclassB
都有若干關聯到其他case類,並且在編譯這個示例時,在運行時嘗試解析這些子類型時失敗。總而言之,將會有幾十個case類構成返回數據的層次結構。
我也試過用for
理解構建這個,但是沒有運氣。
任何人都可以在這裏建議更好的模式?
UPDATE
下似乎有更多的可擴展的模式,但類型不會合作:
implicit def ModelDecodeJson: DecodeJson[Model] =
DecodeJson(c =>
(c.as[ModelSubclassA] ||| c.as[ModelSubclassB]).asInstanceOf[DecodeResult[Model]]
)
Error:(10, 17) type mismatch; found : argonaut.DecodeResult[ModelSubclassB] required: argonaut.DecodeResult[Product with Serializable with Model] Note: ModelSubclassB <: Product with Serializable with Model, but class DecodeResult is invariant in type A. You may wish to define A as +A instead. (SLS 4.5) ||| c.as[ModelSubclassB]).asInstanceOf[DecodeResult[Model]] ^
所以我開始尋找在源和實現的定義DecodeResult
已更改爲包含+A
,如版本6.2-M1中的錯誤所示。不幸的是,升級到該版本時,所有Model
子類編解碼器都變成了含糊不清的含義,這很有意義。
啊...