Search code examples
sprayspray-jsonspray-clientspray-dsl

Spray : How to Unmarshal a response of JsArray or JsObject (ie JsValue) in pipeline


I am creating a service that aggregates data and will need to be able to read any unknown JSON document. I have the pipeline defined as follows:

  private def pipeline = (
       addHeader("Accept", "application/json")
    ~> sendReceive
    ~> unmarshal[JsObject] // Need this to work for JsObject or JsArray //
    ~> recover
  )

This will work with a JsObject but not a JsArray. If I change it to a JsArray then it will not (of course) work with a JsObject. My recover method returns a JsObject.

I would love to be able to define this as a JsValue or enforce a Root format, but for JsValue I get the following compiler error:

could not find implicit value for evidence parameter of type spray.httpx.unmarshalling.FromResponseUnmarshaller[spray.json.JsValue]

And Root Formats also error.

I am not sure how to accomplish what I need, any help would be appreciated.


Solution

  • Use Either, Eric! :) If the response will be either JsObject or JsArray then Either is good solution.

    private def pipeline =
           addHeader("Accept", "application/json")
        ~> sendReceive
        ~> unmarshal[Either[JsObject, JsArray]]
        ~> recover
    

    However, beware that unmarshal[Either[JsObject, JsArray]] tries to parse response as JsObject first and if it fails, tries to parse it as JsArray. This may lead some performance issues.