Skip to content
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

Open
wants to merge 67 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
f02c935
Create attachment.md
glennblock Oct 12, 2014
b391e7c
Update attachment.md
glennblock Oct 12, 2014
0eced3d
Update attachment.md
glennblock Oct 12, 2014
e3b92e8
Update attachment.md
glennblock Oct 12, 2014
63b03e3
Update attachment.md
glennblock Oct 12, 2014
e93235b
Update attachment.md
glennblock Oct 12, 2014
6dda53c
Update attachment.md
glennblock Oct 12, 2014
c3b93a9
Update attachment.md
glennblock Oct 12, 2014
039d474
Update attachment.md
glennblock Oct 12, 2014
69a8356
Update attachment.md
glennblock Oct 12, 2014
c2e5850
Update attachment.md
glennblock Oct 12, 2014
1be8395
Update attachment.md
glennblock Oct 12, 2014
520087b
Update attachment.md
glennblock Oct 12, 2014
9a7552d
Update attachment.md
glennblock Oct 12, 2014
e1e5030
Update attachment.md
glennblock Oct 12, 2014
d0938f3
Update attachment.md
glennblock Oct 12, 2014
fb64e28
Update attachment.md
glennblock Oct 12, 2014
51c14a0
Update attachment.md
glennblock Oct 12, 2014
0bfb4cc
Update attachment.md
glennblock Oct 12, 2014
408f82c
Update attachment.md
glennblock Oct 12, 2014
a981729
Update attachment.md
glennblock Oct 12, 2014
a2c0630
Update attachment.md
glennblock Oct 12, 2014
6a8f54d
Update attachment.md
glennblock Oct 12, 2014
721d14a
Update attachment.md
glennblock Oct 12, 2014
e93abb5
Update attachment.md
glennblock Oct 12, 2014
2215c4d
Update attachment.md
glennblock Oct 13, 2014
f6417da
Update attachment.md
glennblock Oct 13, 2014
bcd8749
Update attachment.md
glennblock Oct 13, 2014
8fc28a1
Update attachment.md
glennblock Oct 13, 2014
982693c
Update attachment.md
glennblock Oct 13, 2014
bcc4eef
Update attachment.md
glennblock Oct 13, 2014
b30afd3
Update attachment.md
glennblock Oct 13, 2014
097cc05
Update attachment.md
glennblock Oct 13, 2014
638e034
Update attachment.md
glennblock Oct 13, 2014
226dda9
Update attachment.md
glennblock Oct 13, 2014
0ed24f4
Updating details for live example
glennblock Oct 15, 2014
ac7a3bd
Update attachment.md
glennblock Oct 15, 2014
b2289c0
Update attachment.md
glennblock Oct 15, 2014
98976f5
Update attachment.md
glennblock Oct 16, 2014
68a46e2
Update attachment.md
glennblock Oct 16, 2014
b77b683
Update attachment.md
glennblock Oct 16, 2014
afd4a7f
Update attachment.md
glennblock Oct 16, 2014
1c50b87
Update attachment.md
glennblock Oct 16, 2014
ced21ae
Update attachment.md
glennblock Oct 16, 2014
9551375
Update attachment.md
glennblock Oct 16, 2014
ca93e81
Update attachment.md
glennblock Oct 16, 2014
09f24dc
Update attachment.md
glennblock Oct 16, 2014
b069860
Update attachment.md
glennblock Oct 16, 2014
82720a7
Update attachment.md
glennblock Oct 16, 2014
db25065
Update attachment.md
glennblock Oct 16, 2014
e22accb
Update attachment.md
glennblock Oct 16, 2014
b74332d
Update attachment.md
glennblock Oct 16, 2014
96eddfc
Update attachment.md
glennblock Oct 16, 2014
154886b
Update attachment.md
glennblock Oct 16, 2014
f49e75a
Update attachment.md
glennblock Oct 16, 2014
9bb8c4b
Update attachment.md
glennblock Oct 16, 2014
06868bb
Update attachment.md
glennblock Oct 16, 2014
6a79d1b
Update attachment.md
glennblock Oct 16, 2014
3a949cd
Update attachment.md
glennblock Oct 16, 2014
b87e14e
Update attachment.md
glennblock Oct 16, 2014
4b2c6ac
Update attachment.md
glennblock Oct 16, 2014
a39f626
Update attachment.md
glennblock Oct 16, 2014
b8179bb
Update attachment.md
glennblock Oct 16, 2014
7446176
Update attachment.md
glennblock Oct 16, 2014
e054a5b
Update attachment.md
glennblock Oct 16, 2014
688db86
Update attachment.md
glennblock Oct 16, 2014
d233882
Update attachment.md
glennblock Oct 16, 2014
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
159 changes: 159 additions & 0 deletions attachment.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
# Attachment extension
Copy link
Member

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

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.

Copy link
Member

Choose a reason for hiding this comment

The 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?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add a line defining the new value for the existing render property of a link object. use the above text as a guide.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • if the attachment property is missing, the client SHOULD treat the data element as a text element.

Copy link
Author

Choose a reason for hiding this comment

The 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.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually, it should read:

"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."

this is to cover future cases where there may be other values for attachment or there are changes to the contentType property.

Copy link
Author

Choose a reason for hiding this comment

The 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
multipart/form-data but no attachments are present?

On Wednesday, October 15, 2014, Mike Amundsen [email protected]
wrote:

In attachment.md:

+A client MAY receive a CollectionJson document containing a Write template which accepts attachments which the client can use to send files.
+
+### Content-type property
+This extension defines a new optional property for the template object: content-type. The two valid values for content-type 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 documents) If the content-type property is missing, clients SHOULD use application/vnd.collection+json when sending a CJ document. If the content-type property is not supported and/or the provided value is not understood by the client, the client MUST use application/vnd.collection+json when sending CJ documents.
+
+### 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) If the client does not support the attachment property and/or the value of this property is not understood, the client MUST treat the data element as a text element.
+

actually, it should read:

"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."

this is to cover future cases where there may be other values for
attachment or there are changes to the contentType property.


Reply to this email directly or view it on GitHub
https://github.com/collection-json/extensions/pull/7/files#r18935874.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep, that's one case. or somehow in the future attachment:null means something to some other extension, for example.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

content looks good to me. there are some typo/spelling nits:

  • This extension outlines an extension...
  • This extension compiles with RFC2388...
  • Receving attachments

there may be others.

Copy link
Author

Choose a reason for hiding this comment

The 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:

  • For each data object in the write template there SHOULD be:
    • A separate part for the data object.
    • A content-disposition header of type form-data with a name parameter
      matching the template object name.
    • If the template data object has "attachment":"true" then the
      content-disposition header MAY contain a filename parameter.
    • If the template data object has "attachment":"true" then the body
      SHOULD contain the file contents.
    • If the template data object does not have "attachment":"true" then
      body SHOULD contain a value.

On Wed, Oct 15, 2014 at 10:02 PM, Mike Amundsen [email protected]
wrote:

In attachment.md:

+A client MAY receive a CollectionJson document containing a Write template which accepts attachments which the client can use to send files.
+
+### Content-type property
+This extension defines a new optional property for the template object: content-type. The two valid values for content-type 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 documents) If the content-type property is missing, clients SHOULD use application/vnd.collection+json when sending a CJ document. If the content-type property is not supported and/or the provided value is not understood by the client, the client MUST use application/vnd.collection+json when sending CJ documents.
+
+### 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) If the client does not support the attachment property and/or the value of this property is not understood, the client MUST treat the data element as a text element.
+

content looks good to me. there are some typo/spelling nits: - This
extension outlines an extension... - This extension compiles with
RFC2388... - Receving attachments there may be others.


Reply to this email directly or view it on GitHub
https://github.com/collection-json/extensions/pull/7/files#r18938402.

Copy link
Author

Choose a reason for hiding this comment

The 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
issues that came up. I made some slight changes to this wording (this is
the final)

  • application/vnd.collection+json - This is the one to use for sending
    regular CJ items. If the content-type 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 documents.

Also I now use Collection+JSON once at the beginning and then CJ everywhere
else.

On Wed, Oct 15, 2014 at 10:02 PM, Mike Amundsen [email protected]
wrote:

In attachment.md:

+A client MAY receive a CollectionJson document containing a Write template which accepts attachments which the client can use to send files.
+
+### Content-type property
+This extension defines a new optional property for the template object: content-type. The two valid values for content-type 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 documents) If the content-type property is missing, clients SHOULD use application/vnd.collection+json when sending a CJ document. If the content-type property is not supported and/or the provided value is not understood by the client, the client MUST use application/vnd.collection+json when sending CJ documents.
+
+### 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) If the client does not support the attachment property and/or the value of this property is not understood, the client MUST treat the data element as a text element.
+

content looks good to me. there are some typo/spelling nits: - This
extension outlines an extension... - This extension compiles with
RFC2388... - Receving attachments there may be others.


Reply to this email directly or view it on GitHub
https://github.com/collection-json/extensions/pull/7/files#r18938402.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for the Write Template section[0]

  • ​replace instances of content-type with contentType
  • replace "compile" with "complies"
  • normalize the use of "NOTE:....." in the Attachment Property section vs.
    inline text in the ContentType section. I like the NOTE format, but it's up
    to you.

If you want to talk about body parts, I think you need to identify them in
the Example.

for the Multipart Requests section[1]

  • normalize references to data object, template object, & template data
    object.
  • change attachements to attachments

[0]
https://github.com/glennblock/extensions/blob/master/attachment.md#write-template
[1]
https://github.com/glennblock/extensions/blob/master/attachment.md#mulipart-requests

Copy link
Author

Choose a reason for hiding this comment

The 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
parts from the draft doc [1] which defines what a part is.

[1] -
https://tools.ietf.org/html/draft-ietf-appsawg-multipart-form-data-05#section-5

On Wed, Oct 15, 2014 at 11:40 PM, Mike Amundsen [email protected]
wrote:

In attachment.md:

+A client MAY receive a CollectionJson document containing a Write template which accepts attachments which the client can use to send files.
+
+### Content-type property
+This extension defines a new optional property for the template object: content-type. The two valid values for content-type 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 documents) If the content-type property is missing, clients SHOULD use application/vnd.collection+json when sending a CJ document. If the content-type property is not supported and/or the provided value is not understood by the client, the client MUST use application/vnd.collection+json when sending CJ documents.
+
+### 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) If the client does not support the attachment property and/or the value of this property is not understood, the client MUST treat the data element as a text element.
+

for the Write Template section[0] - ​replace instances of content-type
with contentType - replace "compile" with "complies" - normalize the use of
"NOTE:....." in the Attachment Property section vs. inline text in the
ContentType section. I like the NOTE format, but it's up to you. If you
want to talk about body parts, I think you need to identify them in the
Example. for the Multipart Requests section[1] - normalize references to
data object, template object, & template data object. - change attachements
to attachments [0]
https://github.com/glennblock/extensions/blob/master/attachment.md#write-template
[1]
https://github.com/glennblock/extensions/blob/master/attachment.md#mulipart-requests


Reply to this email directly or view it on GitHub
https://github.com/collection-json/extensions/pull/7/files#r18940127.

### 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.
Copy link
Member

Choose a reason for hiding this comment

The 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 content-Disposition header MUST appear, but 2388 is vague. any reason we shouldn't just adopt the new I-D language here?

* If the template `data` object has `"attachment":"true"` then the `content-disposition` header MAY contain a `filename` parameter.
Copy link
Member

Choose a reason for hiding this comment

The 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 filename SHOULD appear, but 2388 is unclear. any reason we shouldn't just adopt the new I-D language here?

* If the template `data` object has `"attachment":"true"` then the body SHOULD contain the file contents.
Copy link
Member

Choose a reason for hiding this comment

The 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 value property of the associated data object as a filename and fill the body with the contents of that file" or something more.

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.
Copy link
Member

Choose a reason for hiding this comment

The 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 data object, right?


> __NOTE:__
> At this time, multi-file attachments per template `data` object are not supported.

Copy link
Member

Choose a reason for hiding this comment

The 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?

Copy link
Author

Choose a reason for hiding this comment

The 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.

Copy link
Author

Choose a reason for hiding this comment

The 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.
```
Copy link
Member

Choose a reason for hiding this comment

The 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.

Copy link
Author

Choose a reason for hiding this comment

The 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"}
]
}
}
}
}
```