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

documented requestBody #878

Merged
merged 7 commits into from
Feb 7, 2017
Merged
Changes from 3 commits
Commits
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
209 changes: 182 additions & 27 deletions versions/3.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,13 +145,11 @@ By convention, the OpenAPI Specification (OAS) file is named `openapi.json` or `
Primitive data types in the OAS are based on the types supported by the [JSON-Schema Draft 4](http://json-schema.org/latest/json-schema-core.html#anchor8).
Models are described using the [Schema Object](#schemaObject) which is a subset of JSON Schema Draft 4.

An additional primitive data type `"file"` is used by the [Parameter Object](#parameterObject) and the [Response Object](#responseObject) to set the parameter type or the response as being a file.

<a name="dataTypeFormat"></a>Primitives have an optional modifier property `format`.
OAS uses several known formats to more finely define the data type being used.
However, the `format` property is an open `string`-valued property, and can have any value to support documentation needs.
Formats such as `"email"`, `"uuid"`, etc., can be used even though they are not defined by this specification.
Types that are not accompanied by a `format` property follow their definition from the JSON Schema (except for `file` type which is defined above).
Types that are not accompanied by a `format` property follow their definition from the JSON Schema.
The formats defined by the OAS are:


Expand Down Expand Up @@ -580,7 +578,7 @@ Field Name | Type | Description
<a name="operationExternalDocs"></a>externalDocs | [External Documentation Object](#externalDocumentationObject) | Additional external documentation for this operation.
<a name="operationId"></a>operationId | `string` | Unique string used to identify the operation. The id MUST be unique among all operations described in the API. Tools and libraries MAY use the operationId to uniquely identify an operation, therefore, it is recommended to follow common programming naming conventions.
<a name="operationParameters"></a>parameters | [[Parameter Object](#parameterObject) <span>&#124;</span> [Reference Object](#referenceObject)] | A list of parameters that are applicable for this operation. If a parameter is already defined at the [Path Item](#pathItemParameters), the new definition will override it, but can never remove it. The list MUST NOT include duplicated parameters. A unique parameter is defined by a combination of a [name](#parameterName) and [location](#parameterIn). The list can use the [Reference Object](#referenceObject) to link to parameters that are defined at the [OpenAPI Object's parameters](#oasParameters).
<a name="operationRequestBody"></a>requestBody | [[Request Body Object](#requestBodyObject) <span>&#124;</span> [Reference Object](#referenceObject)] | The request body applicable for this operation.
<a name="operationRequestBody"></a>requestBody | [[Request Body Object](#requestBodyObject) <span>&#124;</span> [Reference Object](#referenceObject)] | The request body applicable for this operation. The `requestBody` is only supported in HTTP methods where the [HTTP 1.1 specification](https://tools.ietf.org/html/rfc7231#section-4.3.1) has explicitly defined semantics for request bodies.
Copy link
Member

Choose a reason for hiding this comment

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

What does "is only supported" mean? Does that mean you cannot specify a requestBody in the OAI document in these situations or that the consumer of the OAI document is not required to do anything with the requestBody in these situations? If this is the latter, what impact does this have on tooling authors?

Copy link
Contributor Author

@fehguy fehguy Feb 1, 2017

Choose a reason for hiding this comment

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

It means the spec does not allow, for example, requestBody on GET operations, and as a tooling vendor, you're outside the spec by supporting it.

Copy link
Member

Choose a reason for hiding this comment

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

Thanks, carry on.

Copy link
Member

Choose a reason for hiding this comment

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

The language needs to be stronger. Should say either that it MUST be one of the specific HTTP verbs (meaning using it with GET, DELETE...) will make the spec invalid - OR - that it SHALL be ignored if used with the wrong verbs (meaning, validation will allow it to exist there, but tools can safely ignore).

<a name="operationResponses"></a>responses | [Responses Object](#responsesObject) | **Required.** The list of possible responses as they are returned from executing this operation.
<a name="operationCallbacks"></a>callback responses | [Callback Responses Object](#callbackObject) | The list of possible callback responses as they are returned from executing this operation.
<a name="operationDeprecated"></a>deprecated | `boolean` | Declares this operation to be deprecated. Usage of the declared operation should be refrained. Default value is `false`.
Expand Down Expand Up @@ -742,7 +740,7 @@ There are four possible parameter types.
Field Name | Type | Description
---|:---:|---
<a name="parameterName"></a>name | `string` | **Required.** The name of the parameter. Parameter names are *case sensitive*. <ul><li>If [`in`](#parameterIn) is `"path"`, the `name` field MUST correspond to the associated path segment from the [path](#pathsPath) field in the [Paths Object](#pathsObject). See [Path Templating](#pathTemplating) for further information.<li>For all other cases, the `name` corresponds to the parameter name used based on the [`in`](#parameterIn) property.</ul>
<a name="parameterIn"></a>in | `string` | **Required.** The location of the parameter. Possible values are "query", "header", "path", "formData" or "cookie".
<a name="parameterIn"></a>in | `string` | **Required.** The location of the parameter. Possible values are "query", "header", "path" or "cookie".
<a name="parameterDescription"></a>description | `string` | A brief description of the parameter. This could contain examples of use. [CommonMark syntax](http://spec.commonmark.org/) can be used for rich text representation.
<a name="parameterRequired"></a>required | `boolean` | Determines whether this parameter is mandatory. If the parameter is [`in`](#parameterIn) "path", this property is **required** and its value MUST be `true`. Otherwise, the property MAY be included and its default value is `false`.
<a name="parameterDeprecated"></a> deprecated | `boolean` | Specifies that a parameter is deprecated and should be transitioned out of usage.
Expand Down Expand Up @@ -890,28 +888,6 @@ style: form
explode: true
```

A form data with file type for a file upload:
```json
{
"name": "avatar",
"in": "formData",
"description": "The avatar of the user",
"required": true,
"schema": {
"type": "file"
}
}
```

```yaml
name: avatar
in: formData
description: The avatar of the user
required: true
schema:
type: file
```

#### <a name="requestBodyObject"></a>Request Body Object

Describes a single request body.
Expand Down Expand Up @@ -1124,6 +1100,185 @@ application/json:

```

##### Considerations for file uploads

In contrast with the 2.0 specification, describing `file` input/output content in OpenAPI is
described with the same semantics as any other schema type. Specifically:

```yaml
# content transferred with base64 encoding
schema:
type: string
format: base64
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 byte today. We can change, but needs to be updated in the other section as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

this will be a documentation concern


# content transfered in binary (octet-stream):
schema:
type: string
format: binary

# multiple files:
schema:
type: array
items:
type: string
format: binary
```
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 incorrect. You can't have multiple file uploads with octet-stream, as they have no separator. For multiple files, the schema has to be named.

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

That's multipart. This is octet-stream.

Copy link
Member

Choose a reason for hiding this comment

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

You are right. My bad.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ron just reminded me that we need to have a property with a name, holding the array property. Thus Ron is right, we can document that an array request body without schema property is meaningless and unsupported by all implementations of the tooling (thx @webron )

Copy link
Contributor Author

Choose a reason for hiding this comment

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

+1 @webron


Note that the above examples apply to either input payloads (i.e. file uploads) or response payloads.


A `requestBody` example for submitting a file in a `POST` operation therefore may look like the following:

```yaml
requestBody:
# any media type is accepted, functionally equivalent to `*/*`
application/octet-stream:
content:
schema:
# a binary file of any type
type: string
format: binary
```

In addition, specific media types may be specified:

```yaml
# multiple, specific media types may be specified:
requestBody:
# a binary file of type png or jpeg
content:
'image/png, image/jpeg':
schema:
type: string
format: binary
```

##### Support for x-www-form-urlencoded request bodies

To submit content using form url encoding via RFC 1866, the following
definition may be used:

```yaml
requestBody:
content:
x-www-form-urlencoded:
schema:
type: object
properties:
id:
type: string
format: uuid
address:
# complex types are stringified to support rfc1866
type: object
properties: {}
```

Note that in the above example, the contents in the `requestBody` must be stringified per RFC1866 when being passed to the server. In addition, the `address` field complex object will be strigified as well.

When passing complex objects in the `x-www-form-urlencoded` content type, the default serialization strategy of such properties is described in the `parameterContent` section as `deepObject`.

##### Special Considerations for `mutlipart` content

It is common to use `multipart/form-data` as a `Content-Type` when transferring request bodies to operations. In contrast to 2.0, a `schema` is required to define the input parameters to the operation when using `multipart` content. This allows complex structures as well as supports mechanisms for multiple file uploads.

When passing in `multipart` types, boundaries may be used to separate sections of the content being transferred--thus, the following default `Content-Type`s are defined for `multipart/*`:

* If the property is a primitive, or an array of primitive values, the default Content-Type is `text/plain`
* If the property is complex, or an array of complex values, the default Content-Type is `application/json`
* If the property is a `type: string` with `format: binary` or `format: base64` (aka a file object), the default Content-Type is `application/octet-stream`


Examples:

```yaml
requestBody:
content:
multipart/form-data:
schema:
type: object
properties:
id:
type: string
format: uuid
address:
# default Content-Type for objects is `application/json`
type: object
properties: {}
profileImage:
# default Content-Type for string/binary is `application/octet-stream`
type: string
format: binary
children:
# default Content-Type for arrays is based on the `inner` type (text/plain here)
type: array
items:
type: string
addresses:
# default Content-Type for arrays is based on the `inner` type (object shown, so `application/json` in this example)
type: array
items:
type: '#/definitions/Address'
```

In scenarios where more control is needed over the Content-Type for `multipart` request bodies, an `encoding` attribute is introduced. This attribute is _only_ applicable to `mulitpart/*` request bodies.

Copy link
Member

Choose a reason for hiding this comment

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

Language is okay - this means that a use can choose to define it still, but it will be ignored if not multipart/*.

Copy link
Member

Choose a reason for hiding this comment

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

This should be updated to say the encoding attribute are also applies to application/x-www-form-urlencoded

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fine.

#### <a name="encodingObject"></a>Encoding Object

An object representing multipart region encoding for `requestBody` objects

##### Patterned Fields
Field Pattern | Type | Description
---|:---:|---
<a name="encodingObjectProperty"></a>The property to apply encoding to | [Encoding Property](#encodingProperty) <span>&#124;</span> [Encoding](#encoding) | The field name to apply special encoding attributes to. This field must exist in the schema as a property. To avoid collisions with specification extensions, properties may not begin with `x-`.
Copy link
Member

Choose a reason for hiding this comment

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

What's Encoding Property? Take a look at the type column.

Copy link
Member

Choose a reason for hiding this comment

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

Would also suggest to reverse the restriction. I think it's better to allow x- in properties and not allow extensions here, as you can add the extensions a level up covering this as well.

Copy link
Member

Choose a reason for hiding this comment

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

I agree that not allowing vendor extensions here would be best.


This object can be extended with [Specification Extensions](#specificationExtensions).

#### <a name="encoding"></a>Encoding

A single encoding definition applied to a single schema property

##### Fixed Fields
Field Name | Type | Description
---|:---:|---
<a name="contentType"></a>Content-Type | `string` | **Required.** The content-type to use for encoding a specific property.
Copy link
Member

Choose a reason for hiding this comment

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

media type

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@webron is wrong. Should stay contentType.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

Content Type is here twice. Should it even be here or do we move it to headers?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

oops. I'll remove one of them.

I left it out of the headers section intentionally. Since it describes the serialization strategy it's (a) required and (b) easier to predict in it's own attribute.


This object can be extended with [Specification Extensions](#specificationExtensions).

##### Encoding Object Examples

```yaml
requestBody:
content:
multipart/mixed:
schema:
type: object
properties:
id:
# default is text/plain
type: string
format: uuid
address:
# default is application/json
type: object
properties: {}
historyMetadata:
# need to declare XML format!
description: metadata in XML format
type: object
properties: {}
profileImage:
# default is application/octet-stream, need to declare an image type only!
type: string
format: binary
encoding:
historyMetadata:
# require XML content-type in utf-8 encoding
contentType: application/xml; charset=utf-8
Copy link
Contributor Author

Choose a reason for hiding this comment

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

what about Content-Disposition?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Waiting for @darrelmiller for feedback on this

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Let's add style here, great idea @webron ?

profileImage:
# only accept png/jpeg
contentType: image/png, image/jpeg
```

#### <a name="itemsObject"></a>Items Object

Expand Down