Skip to content

Latest commit

 

History

History
330 lines (241 loc) · 12.3 KB

nats-protocol-binding.md

File metadata and controls

330 lines (241 loc) · 12.3 KB

NATS Protocol Binding for CloudEvents - Version 1.0.3-wip

Abstract

The NATS Protocol Binding for CloudEvents defines how events are mapped to NATS messages.

Table of Contents

  1. Introduction
  1. Use of CloudEvents Attributes
  1. NATS Message Mapping
  1. References

1. Introduction

CloudEvents is a standardized and protocol-agnostic 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 the NATS protocol as client produced and consumed 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.

1.2 Relation to NATS

This specification does not prescribe rules constraining transfer or settlement of event messages with NATS; it solely defines how CloudEvents are expressed in the NATS protocol as client messages that are produced and consumed.

1.3 Content Modes

The CloudEvents specification defines three content modes for transferring events: structured, binary and batch. The NATS protocol binding does not currently support the batch content mode. Every compliant implementation SHOULD support both structured and binary modes.

In the binary content mode, event metadata attributes are placed in message headers and the event data are placed in the NATS message payload. Binary mode is supported as of NATS 2.2, which introduced message headers.

In the structured content mode, event metadata attributes and event data are placed into the NATS message payload using an event format.

1.4 Event Formats

Event formats, used with the structured content mode, define how an event is expressed in a particular data format. All implementations of this specification MUST support the JSON event format.

1.5 Security

This specification does not introduce any new security features for NATS, or mandate specific existing features to be used.

2. Use of CloudEvents Attributes

This specification does not further define any of the CloudEvents event attributes.

2.1 datacontenttype Attribute

The datacontenttype attribute is assumed to contain a media-type expression compliant with RFC2046.

2.2 data

data is assumed to contain opaque application data that is encoded as declared by the datacontenttype attribute.

An application is free to hold the information in any in-memory representation of its choosing, but as the value is transposed into NATS as defined in this specification, core NATS provides data available as a sequence of bytes.

For instance, if the declared datacontenttype is application/json;charset=utf-8, the expectation is that the data value is made available as UTF-8 encoded JSON text.

3. NATS Message Mapping

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 using two conditions:

  • If the server is a version earlier than NATS 2.2, the content mode is always structured.
  • If the server is version 2.2 or above and the Content-Type header of application/cloudevents is present (matched case-insensitively), then the message is in structured mode, otherwise it is using binary mode.

If the content mode is structured then the NATS message payload MUST be the JSON event format serialized as specified by the UTF-8 encoded JSON text for use in NATS.

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 Event Data Encoding

The data byte-sequence is used as the message body.

3.1.2 Metadata Headers

All CloudEvents attributes, including extensions, MUST be individually mapped to and from distinct NATS message header.

CloudEvents extensions that define their own attributes MAY define a secondary mapping to NATS headers for those attributes, especially if specific attributes need to align with NATS features or with other specifications that have explicit NATS header bindings. Note that these attributes MUST also still appear in the NATS message as NATS headers with the ce- prefix as noted in NATS Header Names.

3.1.3.1 NATS Header Names

Except where noted, all CloudEvents context attributes, including extensions, MUST be mapped to NATS headers with the same name as the attribute name but prefixed with ce-.

Examples:

* `time` maps to `ce-time`
* `id` maps to `ce-id`
* `specversion` maps to `ce-specversion`
* `datacontenttype` maps to `ce-datacontenttype`

Note: per the NATS design specification, header names are case-insensitive.

3.1.3.2 NATS Header Values

The value for each NATS header is constructed from the respective attribute type's canonical string representation.

Some CloudEvents metadata attributes can contain arbitrary UTF-8 string content, and per RFC7230, section 3, NATS headers MUST only use printable characters from the US-ASCII character set, and are terminated by a CRLF sequence with OPTIONAL whitespace around the header value.

When encoding a CloudEvent as an NATS message, string values represented as NATS header values MUST be percent-encoded as described below. This is compatible with RFC3986, section 2.1 but is more specific about what needs encoding. The resulting string SHOULD NOT be further encoded. (Rationale: quoted string escaping is unnecessary when every space and double-quote character is already percent-encoded.)

When decoding an NATS message into a CloudEvent, any NATS header value MUST first be unescaped with respect to double-quoted strings, as described in RFC7230, section 3.2.6. A single round of percent-decoding MUST then be performed as described below. NATS headers for CloudEvent attribute values do not support parenthetical comments, so the initial unescaping only needs to handle double-quoted values, including processing backslash escapes within double-quoted values. Header values produced via the percent-encoding described here will never include double-quoted values, but they MUST be supported when receiving events, for compatibility with older versions of this specification which did not require double-quote and space characters to be percent-encoded.

Percent encoding is performed by considering each Unicode character within the attribute's canonical string representation. Any character represented in memory as a Unicode surrogate pair MUST be treated as a single Unicode character. The following characters MUST be percent-encoded:

  • Space (U+0020)
  • Double-quote (U+0022)
  • Percent (U+0025)
  • Any characters outside the printable ASCII range of U+0021-U+007E inclusive

Attribute values are already constrained to prohibit characters in the range U+0000-U+001F inclusive and U+007F-U+009F inclusive; however for simplicity and to account for potential future changes, it is RECOMMENDED that any NATS header encoding implementation treats such characters as requiring percent-encoding.

Space and double-quote are encoded to avoid requiring any further quoting. Percent is encoded to avoid ambiguity with percent-encoding itself.

Steps to encode a Unicode character:

  • Encode the character using UTF-8, to obtain a byte sequence.
  • Encode each byte within the sequence as %xy where x is a hexadecimal representation of the most significant 4 bits of the byte, and y is a hexadecimal representation of the least significant 4 bits of the byte.

Percent-encoding SHOULD be performed using upper-case for values A-F, but decoding MUST accept lower-case values.

When performing percent-decoding (when decoding an NATS message to a CloudEvent), values that have been unnecessarily percent-encoded MUST be accepted, but encoded byte sequences which are invalid in UTF-8 MUST be rejected. (For example, "%C0%A0" is an overlong encoding of U+0020, and MUST be rejected.)

Example: a header value of "Euro € 😀" SHOULD be encoded as follows:

  • The characters, 'E', 'u', 'r', 'o' do not require encoding
  • Space, the Euro symbol, and the grinning face emoji require encoding. They are characters U+0020, U+20AC and U+1F600 respectively.
  • The encoded NATS header value is therefore "Euro%20%E2%82%AC%20%F0%9F%98%80" where "%20" is the encoded form of space, "%E2%82%AC" is the encoded form of the Euro symbol, and "%F0%9F%98%80" is the encoded form of the grinning face emoji.

3.1.4 Example

This example shows the binary mode mapping of an event in client messages that are produced and consumed.

------------------ Message -------------------

Subject: mySubject

------------------ header --------------------

ce-specversion: 1.0
ce-type: com.example.someevent
ce-time: 2018-04-05T03:56:24Z
ce-id: 1234-1234-1234
ce-source: /mycontext/subcontext
ce-datacontenttype: application/json


------------------ payload -------------------

{
  ... application data ...
}

-----------------------------------------------

3.2 Structured Content Mode

The chosen event format defines how all attributes, including the payload, are represented.

The event metadata and data MUST then be rendered in accordance with the event format specification and the resulting data becomes the payload.

3.2.1 Example

This example shows a JSON event format encoded event in client messages that are produced and consumed.

------------------ Message -------------------

Subject: mySubject

------------------ payload -------------------

{
    "specversion" : "1.0",
    "type" : "com.example.someevent",

    ... further attributes omitted ...

    "data" : {
        ... application data ...
    }
}

-----------------------------------------------

4. References

  • NATS The NATS Messaging System
  • NATS-PUB-PROTO The NATS protocol for messages published by a client
  • NATS-MSG-PROTO The NATS protocol for messages received by a client
  • RFC2046 Multipurpose Internet Mail Extensions (MIME) Part Two: Media Types
  • RFC2119 Key words for use in RFCs to Indicate Requirement Levels
  • RFC3629 UTF-8, a transformation format of ISO 10646
  • RFC7159 The JavaScript Object Notation (JSON) Data Interchange Format