Question: Ref resolution outside of validation?
Closed this issue · 2 comments
By introducing this library into our code, we have been able to leverage additional JSON schema features, such as $ref
resolution, for JSON validation.
Beyond validation, we are parsing valid JSON payloads into our own domain types using JSON schemas.
For illustration, we have something like this:
trait Value
case class BooleanValue private(value: Boolean) extends Value
case class StringValue private(value: String) extends Value
case class IntegerValue private(value: BigInt) extends Value
case class NumberValue private(value: BigDecimal) extends Value
case class DateTimeValue private(value: OffsetDateTime) extends Value
object Value {
def fromBoolean(value: Boolean): Value = BooleanValue(value)
def fromInteger(value: BigInt): Value = IntegerValue(value)
def fromNumber(value: BigDecimal): Value = NumberValue(value)
def fromString(value: String, format: Option[String]): Value = format match {
case Some(f) if f == "date-time" =>
DateTimeValue(OffsetDateTime.parse(value, DateTimeFormatter.ISO_OFFSET_DATE_TIME))
case _ =>
StringValue(value)
}
}
case class Element(path: JsPath, value: Value)
def validatedElements(
schema: SchemaType,
json: JsValue
): Either[Seq[(JsPath, Seq[ValidationError])], List[Element]] = ???
validatedElements
here recursively walks the schema and flattens the JSON payload into a list of JsPath-Value pairs using the corresponding SchemaType
for each leaf of the JSON payload.
Given a schema such as
{
"type": "object",
"properties": {
"organization": {
"allOf": [
{ "$ref": "#/definitions/organization" }
]
}
},
"definitions": {
"organization": {
"type": "object",
"properties": {
"createdAt": { "type": "string", "format": "date-time" }
},
"required": ["createdAt"],
"additionalProperties": false
}
}
}
we would like to parse a valid payload into
List(
Element(JsPath("/organization/createdAt"), aDateTimeValue)
)
We are able to validate the incoming JSON payload with a SchemaValidator()
. However, we have not been able to use the same schema to parse the JSON payload, correctly handling ref resolution. As far as I can tell, all ref resolution / ref caching is package-private.
My question is:
(a) is there a way to achieve this already?
(b) if not, would it be within the scope of this library to open up ref resolution for traversing JSON schemas outside of validation? If so, I'd be happy to crack at it.
(a) No, unfortunately not. All there is are the overloads of the validate
methods of the SchemaValidator
which allow you to pass in additional Reads[A]
that utilize Play JSON Reads to convert a JsValue
into A
. This was enough for our initial needs to retrieve a domain type from a JsValue
, but I don't think it fits your needs.
(b) Yes, I think it is definitely in the scope of the library to provide a generic way to traverse a JSON schema (perhaps, validation then also might become an instance of traversing the schema). So, yes, please go ahead. I currently don't have much time but if I can be of any help, let me know. If you find any issues or have any questions, you can of course also drop me a mail.
Sounds good—thanks @edgarmueller