簡體   English   中英

為播放框架http響應創建可寫[Argonaut.Json]

[英]creating Writeable[Argonaut.Json] for play framework http response

我試圖改變這個函數的實現從使用播放json庫這樣

def apply[T](action: => ApiResponse[T])(implicit tjs: Writes[T], ec: ExecutionContext): Future[Result] = {
    action.fold(
      err =>
        Status(err.statusCode) {
          JsObject(Seq(
            "status" -> JsString("error"),
            "statusCode" -> JsNumber(err.statusCode),
            "errors" -> Json.toJson(err.errors)
          ))
        },
      t =>
        Ok {
          JsObject(Seq(
            "status" -> JsString("ok"),
            "response" -> Json.toJson(t)
          ))
        }
    )
  }

像這樣使用argonaut

def apply[T](action: => ApiResponse[T])(implicit encodeJson: EncodeJson[T], ec: ExecutionContext): Future[Result] = {
    action.fold(
      err =>
        Status(err.statusCode) {
          Json(
          "status" -> jString("error"),
          "statusCode" -> jNumber(err.statusCode),
          "errors" -> err.errors.asJson
          )
        },
      t =>
        Ok {
          Json(
          "status" -> jString("ok"),
          "response" -> t.asJson
          )
        }
    )
  }

但我明白了

無法將argonaut.Json的實例寫入HTTP響應。 嘗試定義一個可寫[argonaut.Json]

對於Status {}阻止和Ok {}阻止,我在這里得到了一個有用的答案https://groups.google.com/forum/#!topic/play-framework/vBMf72a10Zc

所以我試着像這樣創建隱式轉換

implicit def writeableOfArgonautJson(implicit codec: Codec): Writeable[Json] = {
      Writeable(jsval => codec.encode(jsval.toString))
    }

我認為將json對象轉換為字符串並將其提供給codec.encode,它應該將其轉換為Array [Bytes]但我得到

無法猜測用於argonaut.Json的內容類型。 嘗試定義ContentTypeOf [argonaut.Json]

jsval.nospaces.getBytes也返回Array [Bytes]所以我不知道是否可以用它來幫助

所以雖然我認為最后一條錯誤消息意味着我只需要告訴它它應該使用內容類型application.json我也覺得這可能是一個不必要的兔子洞,應該有一個更簡單的方法來做到這一點。

編輯:它不是這樣一個兔子洞,因為定義contentType至少有東西編譯,但我仍然想知道這是否正確

您似乎已回答了自己的問題,但要確認, Writable[A]是:

  1. 如何將類型A轉換為Array[Bytes]
  2. 在響應中使用什么內容類型,這也需要
  3. 當前的字符編碼

字符編碼由隱式Codec實例處理,因此您需要一個隱式的ContentTypeOf[A] ,其中Aargonaunt.Json

implicit def contentTypeOf_ArgonautJson(implicit codec: Codec): ContentTypeOf[argonaut.Json] = {
  ContentTypeOf[argonaut.Json](Some(ContentTypes.JSON))
}

然后是Writable[A] ,它在A上有一個類型約束 ,它有一個范圍內的ContentTypeOf[A] (你剛剛定義過):

implicit def writeableOf_ArgonautJson(implicit codec: Codec): Writeable[argonaut.Json] = {
  Writeable(jsval => codec.encode(jsval.toString))
}

正如你所指出的,那里有一個兔子洞。 事實上,當你考慮到現在可以在你想要的Ok(myArgonautObject)動作中做Ok(myArgonautObject)而沒有進一步的轉換和標題設置樣板時,它肯定似乎有點轉移,但沒有多少額外的代碼。

也許您可以將這些ExtraJsonHelpers放在ExtraJsonHelpers特性中並將其混合到您的控制器中,以便更多地減少樣板。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM