- From: Tomasz Pluskiewicz via GitHub <sysbot+gh@w3.org>
- Date: Wed, 17 Jul 2019 07:35:48 +0000
- To: public-hydra-logs@w3.org
tpluscode has just created a new issue for https://github.com/HydraCG/Specifications:
== Another take on non-RDF payloads (aka file upload) ==
## Describe the requirement
We've approached the problem of non-RDF media types a few times already. Unfortunately it seems that each time it was not focused enough. Either mixed with collections (#187) or lacking broader context (#186).
Looking back at both, I think they are on track, but need a little more refinement.
_For this issues, I'd like to focus on `expects` only and not returned representations_
## Hydra-agnostic example
I would distinguish 3 kinds of requests coming to a Hydra API:
1. RDF payloads - such that are currently described by `expects` and `Class`.
2. Non RDF-payloads
Directly uploading an image instead of RDF:
```http
POST /movie/123/poster-image HTTP/2
Content-Type: image/png
...File bytes...
```
3. `multipart/form-data`
Submitting multiple images **and** RDF data:
```http
PUT /movie/123/image-gallery HTTP/2
Content-Type: multipart/form-data; boundary=----hydra-content
----hydra-content
Content-Disposition: form-data; filename="poster.png"
Content-Type: image/png
...Poster image...
----hydra-content
Content-Disposition: form-data; filename="cast.jpeg"
Content-Type: image/jpeg
...Image of actors...
----hydra-content
Content-Type: application/ld+json
{
"@type": "mov:Gallery",
"description": {
"@value": "Pictures for movie /movie/123"
}
}
----hydra-content
```
Hydra should allow describing operations which `expect` both kinds of file uploads.
## Proposed solutions
It is important to keep support for the current `expect` semantics.
I propose that we extend the existing structure with a media-type description. Unfortunately it is not possible to have it both ways without revolutionising the structure, so the vocab will have to remove `rdfs:range` from `expects` and use `schema:rangeIncludes` instead.
```diff
{
"@id": "hydra:expects",
- "range": "hydra:Class",
+ "schema:rangeIncludes": [
+ "hydra:Class",
+ "hydra:RequestSpecification"
+ ]
},
```
### Example of `hydra:Class` usage
```json
{
"@type": "Operation",
"expects": {
"@type": "RequestSpecification",
"content": {
"@type": "SupportedClassContent",
"class": "mov:Movie"
}
}
}
```
This would be equivalent to `"expects": "mov:Movie"` and both should be supported at least for a while.
### Example of non-RDF payload
```json
{
"@type": "Operation",
"expects": {
"@type": "RequestSpecification",
"content": {
"@type": "RawContent",
"supportedContentType": [ "image/png", "image/jpeg" ]
}
}
}
```
- `supportedContentType` could also use a more elaborate structure though I'm not conviced it's necessary.
### Example of multipart
```json
{
"@type": "Operation",
"expects": {
"@type": "RequestSpecification",
"content": {
"@type": "MultipartContent",
"allowedParts": [
{
"supportedContentType": [ "image/png", "image/jpeg" ],
"maxCount": 2
},
{
"@type": "SupportedClassContent",
"class": "mov:Movie",
"minCount": 1,
"maxCount": 1
}
]
}
}
}
```
Above interpreted as:
- allowing 0-2 image parts
- requiring one RDF-part with `mov:Movie`
- `allowedParts` has same domain as `content`, extended with multipart-specific bit such as the min/max count
`MultipartContent` would have to become part of the core vocabulary.
## Implications
The consequences of such design are far reaching:
1. By introducing `RequestSpecification` we can directly describe HTTP requests (such as by using `expectHeader`)
2. The `content` predicat can be an extension point we've talked about, allowing 3rd party vocab to describe bodies using SHACL. Something like
`ShaclContentSpecification subclassOf ContentSpecification`
3. It will even be possible to define operations which expect markdown, plain text or any other textual format
## Alternative solutions
Here's how Open API does that for [file uploads](https://swagger.io/docs/specification/describing-request-body/file-upload/) and [multipart requests](https://swagger.io/docs/specification/describing-request-body/multipart-requests/). For example
```
requestBody:
content:
multipart/form-data: # Media type
schema: # Request payload
type: object
properties: # Request parts
id: # Part 1 (string value)
type: string
format: uuid
address: # Part2 (object)
type: object
properties:
street:
type: string
city:
type: string
profileImage: # Part 3 (an image)
type: string
format: binary
```
Note that `id` , `address` and `profileImage` will be separate request parts.
Please view or discuss this issue at https://github.com/HydraCG/Specifications/issues/199 using your GitHub account
Received on Wednesday, 17 July 2019 07:35:51 UTC