Using Spray with spray-json for a system, version:

```
"io.spray" %% "spray-json" % "1.2.6"

```

I cannot figure how to get custom JsonFormat definitions to work for serialization that is being handled by spray-routing.

I've had two separate circumstances that have failed.

**1. Nested Case Classes** 

Basic case class JSON serialization has worked fine 

```
case class Something(a: String, b: String)
implicit val something2Json = jsonFormat3(Something)

```

However if I have a nested case class in the case class to be serialized, I can resolve compile issues by providing another JsonFormat implicit, yet at run-time it refuses to serialize

```
case class Subrecord(value: String)
case class Record(a: String, b: String, subrecord: Subrecord)

object MyJsonProtocol extends DefaultJsonProtocol {
  implicit object SubrecordJsonFormat extends JsonFormat[Subrecord] {
    def write(sub: Subrecord) = JsString(sub.value)
    def read(value: JsValue) = value match {
      case JsString(s) => Subrecord(s)
      case _ => throw new DeserializationException("Cannot parse Subrecord")
    }
  }

  implicit val record2Json = jsonFormat3(Record)
}

```

This will throw a MappingException at runtime, explaining there is no usable value for subrecord

**2. Trait with various 0-N case extensions**

Here I have a trait that serves as a capturing type for a group of case classes. Some of the extending classes have vals while others have no vals and are objects. When serialization occurs, it seems like my implicit defined JsonFormat is completely ignored and I'm just give an empty JsObject, particularly when the actual underlying type was one of the case object's with no vals.

```
sealed trait Errors
sealed trait ErrorsWithReason extends Errors {
  def reason: String
}

case class ValidationError(reason: String) extends ErrorsWithReason
case object EntityNotFound extends Errors
case class DatabaseError(reason: String) extends ErrorsWithReason

object MyJsonProtocol extends DefaultJsonProtocol {
  implicit object ErrorsJsonFormat extends JsonFormat[Errors] {
    def write(err: Errors) = failure match {
      case e: ErrorsWithReason => JsString(e.reason)
      case x => JsString(x.toString())
    }
    def read(value: JsValue) = {
      value match {
        //Really only intended to serialize to JSON for API responses
        case _ => throw new DeserializationException("Can't reliably deserialize Error")
      }
    }
  }
}

```

So given the above, if the actual type being serialized is EntityNotFound, then the serialization becomes a RootJsonFormat turning into `{}`. If it's an ErrorsWithReason then it becomes a RootJsonFormat turning into `{ "reason": "somevalue" }`. I may be confused with how the JsonFormat definition is supposed to work, but it doesn't seem to be using my write method at all and instead has suddenly figured out how to serialize on its own.

**EDIT**

Specific serialization cases are using read/deserialization like:

```
entity(as[JObject]) { json =>
  val extraction: A = json.extract[A]
}

```

And write/serialization with the `complete` directive.

I now am realizing thanks to the first answer posted here that my JsonDefaultProtocol and JsonFormat implementations are for spray-json classes, meanwhile the entity directive extraction in the deserialization is using json4s JObject as opposed to spray-json JsObject.