Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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
Benjamin Geer and SepidehAlassi committed Jun 10, 2020
1 parent f93677d commit 135b039
Show file tree
Hide file tree
Showing 14 changed files with 925 additions and 134 deletions.
39 changes: 36 additions & 3 deletions docs/src/paradox/03-apis/api-v2/editing-resources.md
Expand Up @@ -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.

Expand Down Expand Up @@ -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#",
Expand All @@ -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.
Expand Down
24 changes: 24 additions & 0 deletions docs/src/paradox/03-apis/api-v2/editing-values.md
Expand Up @@ -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).

Expand Down
Expand Up @@ -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.

Expand All @@ -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)
Expand Down Expand Up @@ -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")}")
Expand Down Expand Up @@ -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.

Expand All @@ -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)
Expand Down Expand Up @@ -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")}")
Expand Down

0 comments on commit 135b039

Please sign in to comment.