diff --git a/Makefile b/Makefile index 1fdae6a1f..893c353b6 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,6 @@ verify: @# Use "-x" if you want to skip exernal links @tools/verify-links.sh -v . @echo Running the spec phrase checker: - @tools/verify-specs.sh -v spec.md extensions.md serialization.md + @tools/verify-specs.sh -v spec.md extensions.md json-format.md http-transport-binding.md @echo Running the doc phrase checker: @tools/verify-docs.sh -v . diff --git a/http-transport-binding.md b/http-transport-binding.md new file mode 100644 index 000000000..010245867 --- /dev/null +++ b/http-transport-binding.md @@ -0,0 +1,366 @@ +# HTTP Transport Binding for CloudEvents + +## Abstract + +The HTTP Transport Binding for CloudEvents defines how events are mapped to +HTTP 1.1 request and response messages. + +## Status of this document + +This document is a working draft. + +## Table of Contents + +1. [Introduction](#1-introduction) +- 1.1. [Conformance](#11-conformance) +- 1.2. [Relation to HTTP](#12-relation-to-http) +- 1.3. [Content Modes](#13-content-modes) +- 1.4. [Event Formats](#14-event-formats) +- 1.5. [Security](#15-security) +2. [Use of CloudEvents Attributes](#2-use-of-cloudevents-attributes) +- 2.1. [contentType Attribute](#21-contenttype-attribute) +- 2.2. [data Attribute](#22-data-attribute) +3. [HTTP Message Mapping](#3-http-message-mapping) +- 3.2. [Binary Content Mode](#31-binary-content-mode) +- 3.1. [Structured Content Mode](#32-structured-content-mode) +4. [References](#4-references) + +## 1. Introduction + +[CloudEvents][CE] is a standardized and transport-neutral definition of the +structure and metadata description of events. This specification defines how +the elements defined in the CloudEvents specification are to be used in +[HTTP 1.1][RFC7230] requests and response messages. + +### 1.1. Conformance + +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][RFC2119]. + +### 1.2. Relation to HTTP + +This specification does not prescribe rules constraining the use or handling of +specific [HTTP methods][RFC7231-Section-4], and it also does not constrain the +[HTTP target resource][RFC7230-Section-5-1] that is used for transferring or +soliciting events. + +Events can be transferred with all standard or application-defined HTTP request +methods that support payload body transfers. Events can be also be transferred +in HTTP responses and with all HTTP status codes that permit payload body +transfers. + +All examples herein that show HTTP methods, HTTP target URIs, and HTTP status +codes are non-normative illustrations. + +This specification also applies equivalently to HTTP/2 ([RFC7540][RFC7540]), +which is compatible with HTTP 1.1 semantics. + +### 1.3. Content Modes + +This specification defines two content modes for transferring events: +*structured* and *binary*. Every compliant implementation SHOULD support both +modes. + +In the *structured* content mode, event metadata attributes and event data are +placed into the HTTP request or response body using an [event +format](#14-event-formats). + +In the *binary* content mode, the value of the event `data` attribute is placed +into the HTTP request or response body as-is, with the `contentType` attribute +value declaring its media type; all other event attributes are mapped to HTTP +headers. + +### 1.4. Event Formats + +Event formats, used with the *stuctured* content mode, define how an event is +expressed in a particular data format. All implementations of this +specification MUST support the [JSON event format][JSON-format], but MAY +support any additional, including proprietary, formats. + +### 1.5. Security + +This specification does not introduce any new security features for HTTP, or +mandate specific existing features to be used. This specification applies +identically to [HTTP over TLS]([RFC2818][RFC2818]). + +## 2. Use of CloudEvents Attributes + +This specification does not further define any of the [CloudEvents][CE] event +attributes. + +Two of the event attributes, `contentType` and `data` are handled specially +and mapped onto HTTP constructs, all other attributes are transferred as +metadata without further interpretation. + +This mapping is intentionally robust against changes, including the addition +and removal of event attributes, and also accommodates vendor extensions to the +event metadata. Any mention of event attributes other than `contentType` and +`data` is exemplary. + +### 2.1. contentType Attribute + +The `contentType` attribute is assumed to contain a [RFC2046][RFC2046] +compliant media-type expression. + +### 2.2. data Attribute + +The `data` attribute is assumed to contain opaque application data that is +encoded as declared by the `contentType` attribute. + +An application is free to hold the information in any in-memory representation +of its choosing, but as the value is transposed into HTTP as defined in this +specification, the assumption is that the `data` attribute value is made +available as a sequence of bytes. + +For instance, if the declared `contentType` is +`application/json;charset=utf-8`, the expectation is that the `data` attribute +value is made available as [UTF-8][RFC3629] encoded JSON text to HTTP. + +## 3. HTTP Message Mapping + +The event binding is identical for both HTTP request and response messages. + +The content mode is chosen by the sender of the event, which is either the +requesting or the responding party. Gestures that might allow solicitation of +events using a particular mode might be defined by an application, but are not +defined here. + +The receiver of the event can distinguish between the two modes by inspecting +the `Content-Type` header value. If the value is prefixed with the CloudEvents +media type `application/cloudevents`, indicating the use of a known [event +format](#14-event-formats), the receiver uses *structured* mode, otherwise it +defaults to *binary* mode. + +If a receiver detects the CloudEvents media type, but with an event format that +it cannot handle, for instance `application/cloudevents+avro`, it MAY still +treat the event as binary and forward it to another party as-is. + +### 3.1. Binary Content Mode + +The *binary* content mode accommodates any shape of event data, and allows for +efficient transfer and without transcoding effort. + +#### 3.1.1. HTTP Content-Type + +For the *binary* mode, the HTTP `Content-Type` value maps directly to the +CloudEvents `contentType` attribute. + +#### 3.1.2. Event Data Encoding + +The [`data` attribute](#22-data-attribute) byte-sequence is used as the HTTP +message body. + +#### 3.1.3. Metadata Headers + +All [CloudEvents][CE] attributes with exception of `contentType` and `data` +are individually mapped to and from distinct HTTP message headers. + +##### 3.1.3.1 HTTP Header Names + +The naming convention for the HTTP header mapping of attributes is: + + * Each attribute name MUST be prefixed with "CE-" + * Each attribute name's first character MUST be capitalized + +Examples: + + * `eventTime` maps to `CE-EventTime` + * `eventID` maps to `CE-EventID` + * `cloudEventsVersion` maps to `CE-CloudEventsVersion` + +For the `extensions` attribute, each entry of the `extensions` map +is mapped to a separate HTTP header. The `extensions` attribute itself is +not mapped to a header. + +The naming convention for the `extensions` header mapping of attributes is: + + * Each map entry name MUST be prefixed with "CE-X-" + * Each map entry name's first character MUST be capitalized + +Examples: + + * `example` maps to `CE-X-Example` + * `testExtension` maps to `CE-X-TestExtension` + +##### 3.1.3.2 HTTP Header Values + +The value for each HTTP header is constructed from the respective attribute's +[JSON value][JSON-value] representation, compliant with the [JSON event +format][JSON-format] specification. + +Some CloudEvents metadata attributes can contain arbitrary UTF-8 string +content, and per [RFC7230 Section 3][RFC7230-Section-3], HTTP headers MUST only +use printable characters from the US-ASCII character set, and are terminated by +a CRLF sequence. + +Therefore, and analog to the encoding rules for Universal character set host +names in URIs [RFC3986 3.2.2][RFC3986], the JSON value MUST be encoded as +follows: + +Non-printable ASCII characters and non-ASCII characters MUST first be encoded +according to UTF-8, and then each octet of the corresponding UTF-8 sequence +MUST be percent-encoded to be represented as HTTP header characters, in +compliance with [RFC7230, sections 3, 3.2, 3.2.6][RFC7230-Section-3]. The +rules for encoding of the percent character ('%') apply as defined in +[RFC 3986 Section 2.4.][RFC3986-Section-2-4]. + +JSON objects and arrays are NOT surrounded with single or double quotes. + +#### 3.1.4 Examples + +This example shows the *binary* mode mapping of an event with an HTTP POST +request: + +``` text +POST /someresource HTTP/1.1 +Host: webhook.example.com +CE-CloudEventsVersion: "0.1" +CE-EventType: "com.example.someevent" +CE-EventTime: "2018-04-05T03:56:24Z" +CE-EventID: "1234-1234-1234" +CE-Source: "/mycontext/subcontext" + .... further attributes ... +Content-Type: application/json; charset=utf-8 +Content-Length: nnnn + +{ + ... application data ... +} +``` + +This example shows a response containing an event: + +``` text +HTTP/1.1 200 OK +CE-CloudEventsVersion: "0.1" +CE-EventType: "com.example.someevent" +CE-EventTime: "2018-04-05T03:56:24Z" +CE-EventID: "1234-1234-1234" +CE-Source: "/mycontext/subcontext" + .... further attributes ... +Content-Type: application/json; charset=utf-8 +Content-Length: nnnn + +{ + ... application data ... +} +``` + +### 3.2. Structured Content Mode + +The *structured* content mode keeps event metadata and data together in the +payload, allowing simple forwarding of the same event across multiple routing +hops, and across multiple transports. + +#### 3.2.1. HTTP Content-Type + +The [HTTP `Content-Type`][Content-Type] header MUST be set to the media type of +an [event format](#14-event-formats). + +Example for the [JSON format][JSON-format]: + +``` text +Content-Type: application/cloudevents+json; charset=UTF-8 +``` + +#### 3.2.2. Event Data Encoding + +The chosen [event format](#14-event-formats) defines how all attributes, +including the `data` attribute, are represented. + +The event metadata and data is then rendered in accordance with the event +format specification and the resulting data becomes the HTTP message body. + +#### 3.2.3. Metadata Headers + +Implementations MAY include the same HTTP headers as defined for the [binary +mode](#313-metadata-headers). + +All CloudEvents metadata attributes MUST be mapped into the payload, even if +they are also mapped into HTTP headers. + +#### 3.2.4 Examples + +This example shows a JSON event format encoded event, sent with a PUT request: + +``` text + +PUT /myresource HTTP/1.1 +Host: webhook.example.com +Content-Type: application/cloudevents+json; charset=utf-8 +Content-Length: nnnn + +{ + "cloudEventsVersion" : "0.1", + "eventType" : "com.example.someevent", + + ... further attributes omitted ... + + "data" : { + ... application data ... + } +} + +``` + +This example shows a JSON encoded event retuned in a response: + +``` text + +HTTP/1.1 200 OK +Content-Type: application/cloudevents+json; charset=utf-8 +Content-Length: nnnn + +{ + "cloudEventsVersion" : "0.1", + "eventType" : "com.example.someevent", + + ... further attributes omitted ... + + "data" : { + ... application data ... + } +} + +``` + +## 4. References + +- [RFC2046][RFC2046] Multipurpose Internet Mail Extensions (MIME) Part Two: + Media Types +- [RFC2119][RFC2119] Key words for use in RFCs to Indicate Requirement Levels +- [RFC2818][RFC2818] HTTP over TLS +- [RFC3629][RFC3629] UTF-8, a transformation format of ISO 10646 +- [RFC3986][RFC3986] Uniform Resource Identifier (URI): Generic Syntax +- [RFC4627][RFC4627] The application/json Media Type for JavaScript Object + Notation (JSON) +- [RFC4648][RFC4648] The Base16, Base32, and Base64 Data Encodings +- [RFC6839][RFC6839] Additional Media Type Structured Syntax Suffixes +- [RFC7159][RFC7159] The JavaScript Object Notation (JSON) Data Interchange Format +- [RFC7230][RFC7230] Hypertext Transfer Protocol (HTTP/1.1): Message Syntax + and Routing +- [RFC7231][RFC7231] Hypertext Transfer Protocol (HTTP/1.1): Semantics and + Content +- [RFC7540][RFC7540] Hypertext Transfer Protocol Version 2 (HTTP/2) + +[CE]: ./spec.md +[JSON-format]: ./json-format.md +[Content-Type]: https://tools.ietf.org/html/rfc7231#section-3.1.1.5 +[JSON-Value]: https://tools.ietf.org/html/rfc7159#section-3 +[RFC2046]: https://tools.ietf.org/html/rfc2046 +[RFC2119]: https://tools.ietf.org/html/rfc2119 +[RFC2818]: https://tools.ietf.org/html/rfc2818 +[RFC3629]: https://tools.ietf.org/html/rfc3629 +[RFC3986]: https://tools.ietf.org/html/rfc3986 +[RFC3986-Section-2-4]: https://tools.ietf.org/html/rfc3986#section-2.4 +[RFC4627]: https://tools.ietf.org/html/rfc4627 +[RFC4648]: https://tools.ietf.org/html/rfc4648 +[RFC6839]: https://tools.ietf.org/html/rfc6839#section-3.1 +[RFC7159]: https://tools.ietf.org/html/rfc7159 +[RFC7230]: https://tools.ietf.org/html/rfc7230 +[RFC7231]: https://tools.ietf.org/html/rfc7231 +[RFC7230-Section-3]: https://tools.ietf.org/html/rfc7230#section-3 +[RFC7231-Section-4]: https://tools.ietf.org/html/rfc7231#section-4 +[RFC7230-Section-5-1]: https://tools.ietf.org/html/rfc7230#section-5.1 +[RFC7540]: https://tools.ietf.org/html/rfc7540 \ No newline at end of file diff --git a/json-format.md b/json-format.md new file mode 100644 index 000000000..c32a67dca --- /dev/null +++ b/json-format.md @@ -0,0 +1,210 @@ +# JSON Event Format for CloudEvents + +## Abstract + +The JSON Format for CloudEvents defines how events are expressed in +JavaScript Object Notation (JSON) Data Interchange Format ([RFC8259][RFC8259]). + +## Status of this document + +This document is a working draft. + +## Table of Contents + +1. [Introduction](#1-introduction) +2. [Attributes](#2-attributes) +3. [Envelope](#3-envelope) +4. [References](#4-references) + +## 1. Introduction + +[CloudEvents][CE] is a standardized and transport-neutral definition of the +structure and metadata description of events. This specification defines how +the elements defined in the CloudEvents specification are to be represented in +the JavaScript Object Notation (JSON) Data Interchange Format +([RFC8259][RFC8259]). + +The [Attributes](#2-attributes) section describes the naming conventions and +data type mappings for CloudEvents attributes. + +The [Envelope](#3-envelope) section defines a JSON container for CloudEvents +attributes and an associated media type. + +### 1.1. Conformance + +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][RFC2119]. + +## 2. Attributes + +This section defines how CloudEvents attributes are mapped to JSON. This +specification does not explicitly map each attribute, but provides a generic +mapping model that applies to all current and future CloudEvents attributes. + +### 2.1. Base Type System + +The core [CloudEvents specification][CE] defines a minimal abstract type +system, which this mapping leans on. + +### 2.2. Type System Mapping + +The CloudEvents type system is mapped to JSON types as follows: + +| CloudEvents | JSON +|--------------|------------------------------------------------------------- +| String | [string][JSON-String] +| Binary | [string][JSON-String], [Base64-encoded][base64] binary +| URI | [string][JSON-String] +| Timestamp | [string][JSON-String] +| Map | [JSON object][JSON-Object] +| Object | [JSON value][JSON-Value] + +### 2.3. Mapping Object-typed Attributes + +The CloudEvents `data` attribute is `Object`-typed, meaning that it either +holds a `String`, or a `Binary` value, or a `Map`. `Map` entry values are +also `Object` typed. + +If an implementation determines that the actual type of an `Object` is a +`String`, the value MUST be represented as [JSON string][JSON-String] +expression; for `Binary`, the value MUST represented as [JSON +string][JSON-String] expression containing the [Base64][base64] encoded binary +value; for `Map`, the value MUST be represented as a [JSON object][JSON-Object] +expression, whereby the index fields become member names and the associated +values become the respective member's value. + +### 2.4. Examples + +The following table shows exemplary mappings: + +| CloudEvents | Type | Exemplary JSON Value +|--------------------|----------|------------------------------- +| eventType | String | "com.example.someevent" +| eventTypeVersion | String | "1.0" +| cloudEventsVersion | String | "0.1" +| source | URI | "/mycontext" +| eventID | String | "1234-1234-1234" +| eventTime | Timestamp| "2018-04-05T17:31:00Z" +| contentType | String | "application/json" +| extensions | Map | { "extA" : "vA", "extB", "vB" } +| data | String | "" +| data | Binary | "Q2xvdWRFdmVudHM=" +| data | Map | { "objA" : "vA", "objB", "vB" } + +## 3. Envelope + +Each CloudEvents event can be wholly represented as a JSON object. + +Such a representation uses the media type `application/cloudevents+json` + +All REQUIRED and all not omitted OPTIONAL attributes in the given event MUST +become members of the JSON object, with the respective JSON object member name +matching the attribute name, and the member's type and value being mapped using +the [type system mapping](#22-type-system-mapping). + +### 3.1. Special Handling of the "data" Attribute + +The mapping of the `Object`-typed `data` attribute follows the rules laid out +in [Section 2.3.](#23-mapping-object-typed-attributes), with one additional +rule: + +If an implementation determines that the type of the `data` attribute is +`Binary` or `String`, it MUST inspect the `contentType` attribute to determine +whether it is indicated that the data value contains JSON data. + +If the `contentType` value is ["application/json"][RFC4627], or any media type +with a [structured +json suffix][RFC6839], the implementation MUST translate +the `data` attribute value into a [JSON value][JSON-Value], and set the `data` +member of the envelope JSON object to this JSON value. + +Unlike all other attributes, for which value types are restricted to strings +per the [type-system mapping](#22-type-system-mapping), the resulting `data` +member [JSON value][JSON-Value] is unrestricted, and MAY also contain numeric +and logical JSON types. + +### 3.2. Examples + +Example event with `String`-valued `data`: + +``` JSON +{ + "cloudEventsVersion" : "0.1", + "eventType" : "com.example.someevent", + "eventTypeVersion" : "1.0", + "source" : "/mycontext", + "eventID" : "A234-1234-1234", + "eventTime" : "2018-04-05T17:31:00Z", + "extensions" : { + "comExampleExtension" : "value" + }, + "contentType" : "text/xml", + "data" : "" +} +``` + +Example event with `Binary`-valued data + +``` JSON +{ + "cloudEventsVersion" : "0.1", + "eventType" : "com.example.someevent", + "eventTypeVersion" : "1.0", + "source" : "/mycontext", + "eventID" : "B234-1234-1234", + "eventTime" : "2018-04-05T17:31:00Z", + "extensions" : { + "comExampleExtension" : "value" + }, + "contentType" : "application/vnd.apache.thrift.binary", + "data" : "... base64 encoded string ..." +} +``` + +Example event with JSON data for the "data" member, either derived from +a `Map` or [JSON data](#31-special-handling-of-the-data-attribute) data: + +``` JSON +{ + "cloudEventsVersion" : "0.1", + "eventType" : "com.example.someevent", + "eventTypeVersion" : "1.0", + "source" : "/mycontext", + "eventID" : "C234-1234-1234", + "eventTime" : "2018-04-05T17:31:00Z", + "extensions" : { + "comExampleExtension" : "value" + }, + "contentType" : "application/json", + "data" : { + "appinfoA" : "abc", + "appinfoB" : 123, + "appinfoC" : true + } +} +``` + +## 4. References + +* [RFC2046][RFC2046] Multipurpose Internet Mail Extensions (MIME) Part Two: + Media Types +* [RFC2119][RFC2119] Key words for use in RFCs to Indicate Requirement Levels +* [RFC4627][RFC4627] The application/json Media Type for JavaScript Object + Notation (JSON) +* [RFC4648][RFC4648] The Base16, Base32, and Base64 Data Encodings +* [RFC6839][RFC6839] Additional Media Type Structured Syntax Suffixes +* [RFC8259][RFC8259] The JavaScript Object Notation (JSON) Data Interchange Format + +[CE]: ./spec.md +[JSON-format]: ./json-format.md +[Content-Type]: https://tools.ietf.org/html/rfc7231#section-3.1.1.5 +[JSON-Value]: https://tools.ietf.org/html/rfc7159#section-3 +[JSON-String]: https://tools.ietf.org/html/rfc7159#section-7 +[JSON-Object]: https://tools.ietf.org/html/rfc7159#section-4 +[base64]: https://tools.ietf.org/html/rfc4648#section-4 +[RFC2046]: https://tools.ietf.org/html/rfc2046 +[RFC2119]: https://tools.ietf.org/html/rfc2119 +[RFC4627]: https://tools.ietf.org/html/rfc4627 +[RFC4648]: https://tools.ietf.org/html/rfc4648 +[RFC6839]: https://tools.ietf.org/html/rfc6839#section-3.1 +[RFC8259]: https://tools.ietf.org/html/rfc8259 \ No newline at end of file diff --git a/serialization.md b/serialization.md deleted file mode 100644 index 4ede2297a..000000000 --- a/serialization.md +++ /dev/null @@ -1,65 +0,0 @@ -# CloudEvents Serialization Profile - Version 0.1 - -This document specifies how a CloudEvent is to be serialized into certain -encoding formats. Compliant CloudEvents implementations that support these -formats MUST adhere to these rules for these formats. - -## Table of Contents -- [Notational Conventions](#notational-conventions) -- [JSON](#json) - -## Notational Conventions - -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 [RFC 2119](https://tools.ietf.org/html/rfc2119). - -## JSON - -When serialized in [JSON](https://tools.ietf.org/html/rfc7159) a CloudEvent -MUST adhere to the following format: - -``` -{ - "cloudEventsVersion": "cloudEventsVersion value", - "eventID": "eventID value", - "source": "source value", - "eventType": "eventType value", - "eventTypeVersion": "eventTypeVersion value", - "eventTime": "eventTime value", - "schemaURL": "schemaURL value", - "contentType": "contentType", - "extensions": { - ... extensions values ... - }, - "data": ... data value ... -} -``` - -Notes: -- The use of whitespace is not significant. -- The order of the properties, at any level, is not significant. -- CloudEvent producers MAY include additional properties in the JSON - but receivers MAY choose to ignore them. However, it is RECOMMENDED that - they be placed as children of the `extensions` property. Receivers - MUST NOT treat unknown additional properties as an error and MUST NOT stop - processing of the event as a result of their presence. -- Non-mandatory properties are NOT REQUIRED to be included in the JSON, but - if they are present then they MUST adhere to the format described. - -Example: -``` -{ - "cloudEventsVersion": "0.1", - "eventID": "6480da1a-5028-4301-acc3-fbae628207b3", - "source": "http://example.com/repomanager", - "eventType": "com.example.repro.create", - "eventTypeVersion": "v1.5", - "eventTime": "2018-04-01T23:12:34Z", - "schemaURL": "https://product.example.com/schema/repo-create", - "contentType": "application/json", - "data": { - "path": "/JaneDoe/repos/mycode" - } -} -``` diff --git a/spec.md b/spec.md index c3b1339ec..ba578197a 100644 --- a/spec.md +++ b/spec.md @@ -25,10 +25,10 @@ Enter CloudEvents, a specification for describing event data in a common way. CloudEvents seeks to ease event declaration and delivery across services, platforms and beyond. -The [Serialization Profile](serialization.md) specifies how to -serialize a CloudEvent into certain encoding formats. Compliant CloudEvents -implementations that support those formats MUST adhere to the encoding rules -specified in the profile for those formats. +Event Formats specify how to serialize a CloudEvent with certain encoding +formats. Compliant CloudEvents implementations that support those encodings +MUST adhere to the encoding rules specified in the respective event format. +All implementations MUST support the [JSON format][json-format.md]. # Design Goals