-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding extension for attachments #7
base: master
Are you sure you want to change the base?
Changes from all commits
f02c935
b391e7c
0eced3d
e3b92e8
63b03e3
e93235b
6dda53c
c3b93a9
039d474
69a8356
c2e5850
1be8395
520087b
9a7552d
e1e5030
d0938f3
fb64e28
51c14a0
0bfb4cc
408f82c
a981729
a2c0630
6a8f54d
721d14a
e93abb5
2215c4d
f6417da
bcd8749
8fc28a1
982693c
bcc4eef
b30afd3
097cc05
638e034
226dda9
0ed24f4
ac7a3bd
b2289c0
98976f5
68a46e2
b77b683
afd4a7f
1c50b87
ced21ae
9551375
ca93e81
09f24dc
b069860
82720a7
db25065
e22accb
b74332d
96eddfc
154886b
f49e75a
9bb8c4b
06868bb
6a79d1b
3a949cd
b87e14e
4b2c6ac
a39f626
b8179bb
7446176
e054a5b
688db86
d233882
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
# Attachment extension | ||
This extension supports sending and receiving `Collection+JSON` (CJ) documents containing file attachments. This approach uses a `multipart/form-data` request for sending attachments and annotated links in the response for surfacing attachments to be downloaded. | ||
|
||
Each of the examples below is based on the existing CJ friends [example](http://amundsen.com/media-types/collection/examples/). | ||
|
||
It is inspired by this [discussion](https://groups.google.com/forum/#!topic/collectionjson/pzdkNGx-aPE) | ||
|
||
The following RFCs/documents form the basis of the approach used by this extension: | ||
|
||
* [1341] (http://www.w3.org/Protocols/rfc1341/7_2_Multipart.html) - The Multipart Content-Type | ||
* [2388] (http://tools.ietf.org/html/rfc2388) - Returning Values from Forms: multipart/form-data | ||
* [draft-multi-part-form-data] (https://tools.ietf.org/html/draft-ietf-appsawg-multipart-form-data-05) - Updates to RFC2388 | ||
* [6266] (http://tools.ietf.org/html/rfc6266) - Use of the Content-Disposition Header Field in the Hypertext Transfer Protocol (HTTP) | ||
|
||
> __NOTE:__ | ||
> The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119](http://tools.ietf.org/html/rfc2119). | ||
|
||
## Live example | ||
To see a response containing attachment links, use the following command or just open in a browser: | ||
|
||
```text | ||
curl http://cj-attachment.azurewebsites.net/friends -v | ||
``` | ||
|
||
You can also grab a specific `friend`, using the `href` for the `item` in the payload. Also you can just as well create a direct request using the short name (first initial + last name) | ||
|
||
```test | ||
curl http://cj-attachment.azurewebsites.net/friends/mamundsen | ||
``` | ||
|
||
To send a `multipart/form-data` request with files, use the following command substituting `thumbnail.png` with your own image. | ||
|
||
```text | ||
curl -0 -v -include --form full-name="John Doe" --form email="[email protected]" --form blog="http://example.org/jdoe" --form avatar="@./thumbnail.png" http://cj-attachment.azurewebsites.net/friends | ||
``` | ||
|
||
After the image is uploaded, you will find it at `http://cj-attachment.azurewebsites.net/avatars?name={file}` i.e. `http://cj-attachment.azurewebsites.net/avatars/name=thumbnail.png` in the previous case. You can open it in a browser and it will download. | ||
|
||
## Receiving Write Templates that accept attachments | ||
A client MAY receive a CJ document containing a _Write Template_ that accepts attachments that the client can use to send files. | ||
|
||
### contentType property | ||
This extension defines a new optional property for the `template` object: `contentType`. The two valid values for `contentType` are: | ||
|
||
* `multipart/form-data` - This is the one to use for uploading attachments. | ||
* `application/vnd.collection+json` - This is the one to use for sending regular CJ `items`. | ||
|
||
> __NOTE:__ | ||
> If the `contentType` property is missing, not supported and/or the client does not understand the provided value, the client MUST use `application/vnd.collection+json` when sending CJ `items`. | ||
|
||
### attachment property | ||
This extension defines a new property for the data object: `attachment`. This property is only valid for data objects that are children of the template object. | ||
|
||
The two valid values for the `attachment` property: | ||
|
||
* `true`- Treat this data element as an attachment to be uploaded | ||
* `false` - Treat this data element as a text element. | ||
|
||
> __NOTE:__ | ||
> If the attachment property is missing or set to a value to client does not understand, the client SHOULD treat the data element as a text element. | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. drop the above two lines as they are covered in the previous mods, right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add a line defining the new value for the existing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The attachment property is only for templates so why do I need to even mention this? If there's no attachment property by default it would just be treated as a standard template prop. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. actually, it should read: "if the this is to cover future cases where there may be other values for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So you mean in the cases where contentType is present and set to On Wednesday, October 15, 2014, Mike Amundsen [email protected]
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yep, that's one case. or somehow in the future There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. content looks good to me. there are some typo/spelling nits:
there may be others. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, I'll fix that. I added these guidelines, which the RFC alone doesn't cover. Some key points to remember in the context of Collection+JSON:
On Wed, Oct 15, 2014 at 10:02 PM, Mike Amundsen [email protected]
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK just copied into Word and did a big spell/grammar check and fixed all
Also I now use Collection+JSON once at the beginning and then CJ everywhere On Wed, Oct 15, 2014 at 10:02 PM, Mike Amundsen [email protected]
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. for the Write Template section[0]
If you want to talk about body parts, I think you need to identify them in for the Multipart Requests section[1]
[0] There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks, I've made the edits (I think). I've added a specific reference to [1] - On Wed, Oct 15, 2014 at 11:40 PM, Mike Amundsen [email protected]
|
||
### Example | ||
Below you can can see the request contains a friend _Write Template_ that specifies a contentType of `multipart/form-data`. The `avatar` data object is marked as an attachment, indicating that a file should be uploaded. | ||
|
||
```javascript | ||
{ | ||
"template" : { | ||
"contentType" : "multipart/form-data", | ||
"data" : [ | ||
{"name" : "full-name", "value" : ""}, | ||
{"name" : "email", "value" : ""}, | ||
{"name" : "avatar", "attachment": "true"} | ||
] | ||
} | ||
} | ||
``` | ||
## Sending items with attachments | ||
A client MAY send a request that contains attachments using the media type `multipart/form-data`. The request contains the data for the _Write Template_ passed as form data via the `content-disposition header` as well as file uploads. | ||
|
||
### Mulipart requests | ||
This extension compiles with [RFC 2388] (http://tools.ietf.org/html/rfc2388) and [draft-multi-part-form-data] (https://tools.ietf.org/html/draft-ietf-appsawg-multipart-form-data-05) for sending requests. You should refer to these documents for guidelines on the proper way to craft the request. | ||
|
||
Some key points to remember in the context of Collection+JSON: | ||
|
||
* For each `data object` in the _Write Template_ there SHOULD be: | ||
* A separate [part] (https://tools.ietf.org/html/draft-ietf-appsawg-multipart-form-data-05#section-5) for the `data` object. | ||
* A `content-disposition` header of type `form-data` with a `name` parameter matching the template `data` object` name. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. https://tools.ietf.org/html/draft-ietf-appsawg-multipart-form-data-05#section-5.2 says |
||
* If the template `data` object has `"attachment":"true"` then the `content-disposition` header MAY contain a `filename` parameter. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. https://tools.ietf.org/html/draft-ietf-appsawg-multipart-form-data-05#section-5.3 says |
||
* If the template `data` object has `"attachment":"true"` then the body SHOULD contain the file contents. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you mean body part, right? and "file contents" is vague. "SHOULD treat the honestly, i thought we were going to avoid this prose by just referring to the RFC2388 and I-D. why is it important to add this in here (just remind me, OK?) |
||
* If the template `data` object does not have `"attachment":"true"` then the body SHOULD contain a value. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is pretty vague: "a value". i think you mean the body part should contain the contents of the value property of the associated |
||
|
||
> __NOTE:__ | ||
> At this time, multi-file attachments per template `data` object are not supported. | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i don't understand any of this "Parts" section. what is a Part? where is it in the example? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A multipart request consists of mulitple parts. The document is a part and the attachment is a part. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added the wording of "Body Part" to make it more explicit. Both "part" and "body part" are used in the RFC. |
||
### Example | ||
Below you can see the request contains three parts. The first two contain textual information for `full-name` and `email`, while the third is an attachment containing the `avatar` image. | ||
``` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i think the text refers to the template example above as well as the HTTP payload below, right? please move text around as needed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
content-type: multipart/form-data, boundary=AaB03x | ||
|
||
--AaB03x | ||
content-disposition: form-data; name="full-name" | ||
content-type: text/plain; charset=us-ascii | ||
John Doe | ||
--AaB03x | ||
content-disposition: form-data; name="email" | ||
content-type: text/plain; charset=us-ascii | ||
[email protected] | ||
--AaB03x | ||
content-disposition: form-data; name="avatar"; filename="jdoe.jpg" | ||
content-type: image/jpeg | ||
... | ||
--AaB03x | ||
``` | ||
## Receiving items with attachment links | ||
A client MAY receive a response that contains `items` with `link` objects that represent downloadable attachments. | ||
|
||
### Attachment render value | ||
A new `render` value of `attachment` is introduced for links. This informs the client that it should treat the `href` for the link as downloadable. | ||
|
||
> __NOTE:__ | ||
> Clients that do not support the `attachment` value for render MUST treat the associated href as a navigation link. | ||
|
||
### Example | ||
Below is an example of a response containing links that are attachments, namely the `avatar` link has a `render` value of `attachment`. The client in this case SHOULD download the associated image. | ||
|
||
```javascript | ||
content-type: application/vnd.collection+json | ||
|
||
{ "collection" : | ||
{ | ||
"version" : "1.0", | ||
"href" : "http://example.org/friends/", | ||
|
||
"items" : [ | ||
{ | ||
"href" : "http://example.org/friends/jdoe", | ||
"data" : [ | ||
{"name" : "full-name", "value" : "John Doe", "prompt" : "Full Name"}, | ||
{"name" : "email", "value" : "[email protected]", "prompt" : "Email"} | ||
], | ||
"links": [ | ||
{"name": "avatar", "rel": "related", "render": "attachment", "href":"http://example.org/images/jdoe.jpg"} | ||
] | ||
}, | ||
{ | ||
"href" : "http://example.org/friends/mamund", | ||
"data" : [ | ||
{"name" : "full-name", "value" : "Mike Amundsen", "prompt" : "Full Name"}, | ||
{"name" : "email", "value" : "[email protected]", "prompt" : "Email"} | ||
], | ||
"links": [ | ||
{"name": "avatar", "rel": "related", "render": "attachment", "href":"http://example.org/images/mamund.jpg"} | ||
] | ||
} | ||
} | ||
} | ||
} | ||
``` | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
very small nit. I'd like to use the abbreviation for collection+json as Cj, not CJ