- 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