Skip to content
Permalink
Browse files

feat(api-v2): Specify custom IRIs when creating resources/values (#1646)

* feat(api-v2): Specify custom IRIs when creating resources/values (ongoing).

* feature (customIRI) test for creation of resource with supplied IRI

* feature (custormIri) allow custom iri for values + test for it

* feature (customIRI) create resources with values that have custom IRIs + test + test data

* feature (customIRI) createValueRequestV2 should accept custom value IRI and assign it to value + test

* feature (customIri) create link values with supplied value IRI

* feature (customIRI) create values with custom uuid

* feature (customIri) test for creation of values with custom UUIDs

* feature (customIri) create values with custom creation date + test

* feature (customIri) more tests + test data

* doc (customIRI) documentation about creation of a resource with custom IRI, value IRIs, and value UUIDs.

* doc (custom IRI) creation of values with custom IRI, UUID, and creation date

* fix (customIri) get rid of the added resource

* refactor (customIri) blank lines added, and description of UUID encoding added to docs

* feature (customIri) create resource with values that have custom creation date + test

Co-authored-by: Sepideh Alassi <sepideh.alassi@gmail.com>
  • Loading branch information
benjamingeer and SepidehAlassi committed Jun 10, 2020
1 parent f93677d commit 135b03955eed26cdcb5d869c22980259b1d328a3
@@ -32,8 +32,8 @@ HTTP POST to http://host/v2/resources
The body of the request is a JSON-LD document in the
@ref:[complex API schema](introduction.md#api-schema), specifying the resource's IRI, type,
and `rdfs:label`, along with its Knora resource properties and their values. The representation of the
resource is the same as when it is returned in a `GET` request, except that its IRI and
`knora-api:attachedToUser`, and those of its values, are not given. The format of the values submitted
resource is the same as when it is returned in a `GET` request, except that its `knora-api:attachedToUser` is not given,
and the resource IRI and those of its values can be optionally specified. The format of the values submitted
is described in @ref:[Editing Values](editing-values.md). If there are multiple values for a property,
these must be given in an array.

@@ -160,7 +160,7 @@ resource's creator can be specfied by adding `knora-api:attachedToUser`. For exa
"knora-api:creationDate" : {
"@type" : "xsd:dateTimeStamp",
"@value" : "2019-01-09T15:45:54.502951Z"
}
},
"@context" : {
"rdf" : "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
"knora-api" : "http://api.knora.org/ontology/knora-api/v2#",
@@ -185,6 +185,39 @@ than the requesting user only if the requesting user is an administrator of the
project or a system administrator. The specified creator must also
have permission to create resources of that class in that project.

In addition to the creation date, in the body of the request, it is possible to specify a custom IRI for a resource through
the `@id` attribute which will then be assigned to the resource; otherwise the resource will get a unique random IRI.
Similarly, it is possible to assign a custom IRI to the values using their `@id` attributes; if not given, random IRIs
will be assigned to the values. An optional custom UUID of a value can also be given by adding `knora-api:valueHasUUID`.
Each custom UUID must be [base64url-encoded](rfc:4648#section-5), without padding. For example:
```jsonld
{
"@id" : "http://rdfh.ch/0001/a-custom-thing",
"@type" : "anything:Thing",
"knora-api:attachedToProject" : {
"@id" : "http://rdfh.ch/projects/0001"
},
"anything:hasInteger" : {
"@id" : "http://rdfh.ch/0001/a-thing/values/int-value-IRI",
"@type" : "knora-api:IntValue",
"knora-api:intValueAsInt" : 10,
"knora-api:valueHasUUID" : "IN4R19yYR0ygi3K2VEHpUQ"
},
"rdfs:label" : "test thing with custom IRI",
"knora-api:creationDate" : {
"@type" : "xsd:dateTimeStamp",
"@value" : "2019-01-09T15:45:54.502951Z"
},
"@context" : {
"rdf" : "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
"knora-api" : "http://api.knora.org/ontology/knora-api/v2#",
"rdfs" : "http://www.w3.org/2000/01/rdf-schema#",
"xsd" : "http://www.w3.org/2001/XMLSchema#",
"anything" : "http://0.0.0.0:3333/ontology/0001/anything/v2#"
}
}
```

The response is a JSON-LD document containing a
@ref:[preview](reading-and-searching-resources.md#get-the-preview-of-a-resource-by-its-iri)
of the resource.
@@ -85,7 +85,31 @@ Permissions for the new value can be given by adding `knora-api:hasPermissions`.
}
}
```
Each value can have an optional custom IRI specified by the `@id` attribute, a custom creation date specified by adding
`knora-api:creationDate` (an [xsd:dateTimeStamp](https://www.w3.org/TR/xmlschema11-2/#dateTimeStamp)), or a custom UUID
given by `knora-api:valueHasUUID`. Each custom UUID must be [base64url-encoded](rfc:4648#section-5), without padding.
For example:


```jsonld
"@id" : "http://rdfh.ch/0001/a-thing",
"@type" : "anything:Thing",
"anything:hasInteger" : {
"@id" : "http://rdfh.ch/0001/a-customized-thing/values/int-value-IRI",
"@type" : "knora-api:IntValue",
"knora-api:intValueAsInt" : 21,
"knora-api:valueHasUUID" : "IN4R19yYR0ygi3K2VEHpUQ",
"knora-api:creationDate" : {
"@type" : "xsd:dateTimeStamp",
"@value" : "2020-06-04T12:58:54.502951Z"
}
},
"@context" : {
"knora-api" : "http://api.knora.org/ontology/knora-api/v2#",
"anything" : "http://0.0.0.0:3333/ontology/0001/anything/v2#",
"xsd" : "http://www.w3.org/2001/XMLSchema#"
}
```
The format of the object of `knora-api:hasPermissions` is described in
@ref:[Permissions](../../02-knora-ontologies/knora-base.md#permissions).

@@ -356,12 +356,12 @@ class KnoraSipiIntegrationV2ITSpec extends ITKnoraLiveSpec(KnoraSipiIntegrationV

val request = Post(s"$baseApiUrl/v2/resources", HttpEntity(RdfMediaTypes.`application/ld+json`, jsonLdEntity)) ~> addCredentials(BasicHttpCredentials(anythingUserEmail, password))
val responseJsonDoc: JsonLDDocument = getResponseJsonLD(request)
stillImageResourceIri.set(responseJsonDoc.body.getIDAsKnoraDataIri.toString)
stillImageResourceIri.set(responseJsonDoc.body.requireIDAsKnoraDataIri.toString)

// Get the resource from Knora.
val knoraGetRequest = Get(s"$baseApiUrl/v2/resources/${URLEncoder.encode(stillImageResourceIri.get, "UTF-8")}")
val resource: JsonLDDocument = getResponseJsonLD(knoraGetRequest)
assert(resource.getTypeAsKnoraTypeIri.toString == "http://0.0.0.0:3333/ontology/0001/anything/v2#ThingPicture")
assert(resource.requireTypeAsKnoraTypeIri.toString == "http://0.0.0.0:3333/ontology/0001/anything/v2#ThingPicture")

// Get the new file value from the resource.

@@ -381,7 +381,7 @@ class KnoraSipiIntegrationV2ITSpec extends ITKnoraLiveSpec(KnoraSipiIntegrationV
case other => throw AssertionException(s"Invalid value object: $other")
}

stillImageFileValueIri.set(savedValueObj.getIDAsKnoraDataIri.toString)
stillImageFileValueIri.set(savedValueObj.requireIDAsKnoraDataIri.toString)

val savedImage = savedValueToSavedImage(savedValueObj)
assert(savedImage.internalFilename == uploadedFile.internalFilename)
@@ -430,7 +430,7 @@ class KnoraSipiIntegrationV2ITSpec extends ITKnoraLiveSpec(KnoraSipiIntegrationV
// Send the JSON in a PUT request to Knora.
val knoraPostRequest = Put(baseApiUrl + "/v2/values", HttpEntity(ContentTypes.`application/json`, jsonLdEntity)) ~> addCredentials(BasicHttpCredentials(anythingUserEmail, password))
val responseJsonDoc = getResponseJsonLD(knoraPostRequest)
stillImageFileValueIri.set(responseJsonDoc.body.getIDAsKnoraDataIri.toString)
stillImageFileValueIri.set(responseJsonDoc.body.requireIDAsKnoraDataIri.toString)

// Get the resource from Knora.
val knoraGetRequest = Get(s"$baseApiUrl/v2/resources/${URLEncoder.encode(stillImageResourceIri.get, "UTF-8")}")
@@ -523,12 +523,12 @@ class KnoraSipiIntegrationV2ITSpec extends ITKnoraLiveSpec(KnoraSipiIntegrationV

val request = Post(s"$baseApiUrl/v2/resources", HttpEntity(RdfMediaTypes.`application/ld+json`, jsonLdEntity)) ~> addCredentials(BasicHttpCredentials(anythingUserEmail, password))
val responseJsonDoc: JsonLDDocument = getResponseJsonLD(request)
pdfResourceIri.set(responseJsonDoc.body.getIDAsKnoraDataIri.toString)
pdfResourceIri.set(responseJsonDoc.body.requireIDAsKnoraDataIri.toString)

// Get the resource from Knora.
val knoraGetRequest = Get(s"$baseApiUrl/v2/resources/${URLEncoder.encode(pdfResourceIri.get, "UTF-8")}")
val resource: JsonLDDocument = getResponseJsonLD(knoraGetRequest)
assert(resource.getTypeAsKnoraTypeIri.toString == "http://0.0.0.0:3333/ontology/0001/anything/v2#ThingDocument")
assert(resource.requireTypeAsKnoraTypeIri.toString == "http://0.0.0.0:3333/ontology/0001/anything/v2#ThingDocument")

// Get the new file value from the resource.

@@ -548,7 +548,7 @@ class KnoraSipiIntegrationV2ITSpec extends ITKnoraLiveSpec(KnoraSipiIntegrationV
case other => throw AssertionException(s"Invalid value object: $other")
}

pdfValueIri.set(savedValueObj.getIDAsKnoraDataIri.toString)
pdfValueIri.set(savedValueObj.requireIDAsKnoraDataIri.toString)

val savedDocument: SavedDocument = savedValueToSavedDocument(savedValueObj)
assert(savedDocument.internalFilename == uploadedFile.internalFilename)
@@ -589,7 +589,7 @@ class KnoraSipiIntegrationV2ITSpec extends ITKnoraLiveSpec(KnoraSipiIntegrationV

val request = Put(s"$baseApiUrl/v2/values", HttpEntity(RdfMediaTypes.`application/ld+json`, jsonLdEntity)) ~> addCredentials(BasicHttpCredentials(anythingUserEmail, password))
val responseJsonDoc: JsonLDDocument = getResponseJsonLD(request)
pdfValueIri.set(responseJsonDoc.body.getIDAsKnoraDataIri.toString)
pdfValueIri.set(responseJsonDoc.body.requireIDAsKnoraDataIri.toString)

// Get the resource from Knora.
val knoraGetRequest = Get(s"$baseApiUrl/v2/resources/${URLEncoder.encode(pdfResourceIri.get, "UTF-8")}")

0 comments on commit 135b039

Please sign in to comment.