Skip to content

Commit

Permalink
feat(api-v2): Control JSON-LD nesting via an HTTP header (DSP-1084) (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
Benjamin Geer committed Nov 18, 2020
1 parent 9170419 commit b13eecf
Show file tree
Hide file tree
Showing 19 changed files with 1,403 additions and 210 deletions.
12 changes: 12 additions & 0 deletions docs/03-apis/api-v2/introduction.md
Expand Up @@ -74,6 +74,18 @@ set of RDF triples, an equivalent JSON-LD response can explicitly
provide data in a hierarchical structure, with objects nested inside
other objects.

### Hierarchical vs. Flat JSON-LD

The client can choose between hierarchical and flat JSON-LD. In hierarchical
JSON-LD, entities with IRIs are inlined (nested) where they are used. If the
same entity is used in more than one place, it is inlined only once, and other
uses just refer to its IRI. In Knora's flat JSON-LD, all entities with IRIs are located
at the top level of the document (in a `@graph` if there is more than one of them).
This setting does not affect blank nodes, which are always inlined (unlike in standard
flat JSON-LD). Knora ontologies are always returned in the `flat` rendering; other kinds
of responses default to `hierarchical`. To use this setting, submit the HTTP header
`X-Knora-JSON-LD-Rendering` with the value `hierarchical` or `flat`.

## Knora IRIs

Resources and entities are identified by IRIs. The format of these IRIs
Expand Down
389 changes: 389 additions & 0 deletions test_data/metadataE2EV2/metadata-flat.jsonld

Large diffs are not rendered by default.

394 changes: 394 additions & 0 deletions test_data/metadataE2EV2/metadata.ttl

Large diffs are not rendered by default.

28 changes: 28 additions & 0 deletions webapi/src/main/scala/org/knora/webapi/OntologySchema.scala
Expand Up @@ -72,6 +72,23 @@ case object MarkupAsStandoff extends MarkupRendering
*/
case object NoMarkup extends MarkupRendering

/**
* A trait representing options that affect the format of JSON-LD responses.
*/
sealed trait JsonLDRendering extends SchemaOption

/**
* Indicates that flat JSON-LD should be returned, i.e. objects with IRIs should be referenced by IRI
* rather than nested. Blank nodes will still be nested in any case.
*/
case object FlatJsonLD extends JsonLDRendering

/**
* Indicates that hierarchical JSON-LD should be returned, i.e. objects with IRIs should be nested when
* possible, rather than referenced by IRI.
*/
case object HierarchicalJsonLD extends JsonLDRendering

/**
* Utility functions for working with schema options.
*/
Expand Down Expand Up @@ -118,4 +135,15 @@ object SchemaOptions {
def renderMarkupAsStandoff(targetSchema: ApiV2Schema, schemaOptions: Set[SchemaOption]): Boolean = {
targetSchema == ApiV2Complex && schemaOptions.contains(MarkupAsStandoff)
}

/**
* Determines whether flat JSON-LD should be returned, i.e. objects with IRIs should be referenced by IRI
* rather than nested.
*
* @param schemaOptions the schema options submitted with the request.
* @return `true` if flat JSON-LD should be returned.
*/
def returnFlatJsonLD(schemaOptions: Set[SchemaOption]): Boolean = {
schemaOptions.contains(FlatJsonLD)
}
}
Expand Up @@ -32,7 +32,7 @@ import spray.json.{JsNumber, JsObject, JsString, JsValue}

/**
* The Knora exception handler is used by akka-http to convert any exceptions thrown during route processing
* into HttpResponses. It is brought implicitly into scope at the top level [[KnoraLiveService]].
* into HttpResponses. It is brought implicitly into scope by the application actor.
*/
object KnoraExceptionHandler extends LazyLogging {

Expand Down Expand Up @@ -156,7 +156,7 @@ object KnoraExceptionHandler extends LazyLogging {
// ... and the HTTP status code.
HttpResponse(
status = httpStatus,
entity = HttpEntity(ContentType(MediaTypes.`application/json`), jsonLDDocument.toCompactString)
entity = HttpEntity(ContentType(MediaTypes.`application/json`), jsonLDDocument.toCompactString(false))
)
}

Expand Down

0 comments on commit b13eecf

Please sign in to comment.