There are several ways of doing this, although none of them is considered idiomatic for Finch. The more-or-less safe way to accept an arbitrary JSON object within an Endpoint
is to drop down to JSON AST API exposed via the JSON library you're using. For json4s it's going to be org.json4s.JsonAST.JValue
.
scala> import io.finch._, io.finch.json4s._, org.json4s._
scala> implicit val formats: Formats = DefaultFormats
formats: org.json4s.Formats = org.json4s.DefaultFormats$@5ee387bc
scala> val e = jsonBody[JsonAST.JValue]
e: io.finch.Endpoint[org.json4s.JsonAST.JValue] = body
scala> e(Input.post("/").withBody[Application.Json](Map("foo" -> 1, "bar" -> "baz"))).awaitValueUnsafe()
res2: Option[org.json4s.JsonAST.JValue] = Some(JObject(List((foo,JInt(1)), (bar,JString(baz)))))
This will give you a JsonAST.JValue
instance that you'd need to manually manipulate with (I assume there is a pattern-matching API exposed for that).
An alternative (and way more dangerous) solution would be to ask Finch/JSON4S to decode a JSON object as Map[String, Any]
. However, this only works if you don't expect your clients sending JSON arrays as top-level entities.
scala> import io.finch._, io.finch.json4s._, org.json4s._
scala> implicit val formats: Formats = DefaultFormats
formats: org.json4s.Formats = org.json4s.DefaultFormats$@5ee387bc
scala> val b = jsonBody[Map[String, Any]]
b: io.finch.Endpoint[Map[String,Any]] = body
scala> b(Input.post("/").withBody[Application.Json](Map("foo" -> 1, "bar" -> "baz"))).awaitValueUnsafe()
res1: Option[Map[String,Any]] = Some(Map(foo -> 1, bar -> baz))