Project: CloudEvents (App Definition and Development / Streaming & Messaging)
File: SDK.md

<!-- no verify-specs --> The intent of this document to describe a minimum set of requirements for new Software Development Kits (SDKs) for CloudEvents. These SDKs are designed and implemented to enhance and speed up CloudEvents integration. As part of community efforts CloudEvents team committed to support and maintain the following SDKs: This is intended to provide guidance and requirements for SDK authors. This document is intended to be kept up to date with the CloudEvents spec. The SDKs are community driven activities and are (somewhat) distinct from the CloudEvents specification itself. In other words, while ideally the SDKs are expected to keep up with changes to the specification, it is not a hard requirement that they do so. It will be continguent on the specific SDK's maintainers to find the time. Being an open source community the CloudEvents team is open for new members as well open to their contributions. In order to ensure that an SDK is going to be supported and maintained the CloudEvents community would like to ensure that: Each SDK has active points of contact. Each SDK supports the latest(N), and N-1, major releases of the \*. Within the scope of a major release, only support for the latest minor version is needed. Support for release candidates is not required, but strongly encouraged. \* Note: v1.0 is a special case and it is recommended that as long as v1.0 is the latest version, SDKs should also support v0.3. Each SDK MUST meet these requirements: Supports CloudEvents at spec milestones and ongoing development version. Encode a canonical Event into a transport specific encoded message. Decode transport specific encoded messages into a Canonical Event. Idiomatic usage of the programming language. Using current language version(s). Supports HTTP transport renderings in both `structured` and `binary` content mode. Each SDK will provide a generic CloudEvents class/object/structure that represents the canonical form of an Event. The SDK should enable users to bypass implementing transport specific encoding and decoding of the CloudEvents `Event` object. The general flow for Objects should be: ``` Event (-> Message) -> Transport ``` and ``` Transport (-> Message) -> Event ``` An SDK is not required to implement a wrapper around the transport, the focus should be around allowing programming models to work with the high level `Event` object, and providing tools to take the `Event` and turn it into something that can be used with the implementation transport selected. At a high level, the SDK needs to be able to help with the following tasks: Compose an Event. Encode an Event given a transport and encoding (into a Transport Message if appropriate). Decode an Event given a transport specific message, request or response (into a Transport Message if appropriate). Provide a convenient way to compose both a single message and many messages. Implementers will need a way to quickly build up and convert their event data into the a CloudEvents encoded Event. In practice there tend to be two aspects to event composition, Event Creation "I have this data that is not formatted as a CloudEvent and I want it to be." Event Mutation "I have a CloudEvents formatted Event and I need it to be a different

"I have a CloudEvents formatted Event and I need to mutate the Event." Event creation is highly idiomatic to the SDK language. Event mutation tends to be solved with an accessor pattern, like getters and setters. But direct key access could be leveraged, or named-key accessor functions. In either case, there MUST be a method for validating the resulting Event object based on the parameters set, most importantly the CloudEvents spec version. Each SDK MUST support encoding and decoding an Event with regards to a transport and encoding: Each SDK MUST support structured-mode messages for each transport that it supports. Each SDK SHOULD support binary-mode messages for each transport that it supports. Each SDK SHOULD support batch-mode messages for each transport that it supports (where the event format and transport combination supports batch mode). Each SDK SHOULD indicate which modes it supports for each supported event format, both in the and in any SDK-specific documentation provided. Note that when decoding an event, media types MUST be matched case-insensitively, as specified in [RFC 2045] (https://tools.ietf.org/html/rfc2045). Data access from the event has some considerations, the Event at rest could be encoded into the `base64` form, as structured data, or as a wire format like `json`. An SDK MUST provide a method for unpacking the data from these formats into a native format. Supporting CloudEvents extensions is idiomatic again, but a method that mirrors the data access seems to work. Validation MUST be possible on an individual Event. Validation MUST take into account the spec version, and all the requirements put in-place by the spec at each version. SDKs SHOULD perform validation on context attribute values provided to it by the SDK user. This will help ensure that only valid CloudEvents are generated. Each SDK must provide examples using at least HTTP transport of: Composing an Event. Encoding and sending a composed Event. Receiving and decoding an Event. Each SDK must update the following "support table" periodically to ensure they accurately the status of each SDK's support for the stated features. <!-- Do these commands in vi with the cursor after these comments. Easiest to edit table by first doing this: :g/^|/s/ :heavycheckmark: / :y: /g and making the window wide enough that lines don't wrap. Then it should look nice. Undo it when done: :g/^|/s/ :y: / :heavycheckmark: /g --> | Feature

C# | Go | Java | JS | PHP | PS | Python | Ruby | Rust | |:-| :-: | :-: | :--: | :-: | :-: | :-: | :-: | :--: | :--: | | | | | :heavycheckmark: | :heavycheckmark: | :heavycheckmark: | :heavycheckmark: | :heavycheckmark: | :heavycheckmark: | :heavycheckmark: | :heavycheckmark: | :heavycheckmark: | | Event Formats | | | :heavycheckmark: | | :x: | :x: | | | | :x: | :x: | | | :heavycheckmark: | | :x: | :x: | | | | | :x: | | | :heavycheckmark: | | :heavycheckmark: | :heavycheckmark: | | | :heavycheckmark: | :heavycheckmark: | :heavycheckmark: | | | :heavycheckmark: | | :heavycheckmark: | :x: | | | | :x: | :x: | | Bindings / Content Modes | | | :heavycheckmark: | | :heavycheckmark: | :x: | | | | :x: | :x: | | | :heavycheckmark: | | :heavycheckmark: | :x: | | | | :x: | :x: | | | :heavycheckmark: | | :heavycheckmark: | :heavycheckmark: | | | :heavycheckmark: | :heavycheckmark: | :heavycheckmark: | | | :heavycheckmark: | | :heavycheckmark: | :heavycheckmark: | | | :heavycheckmark: | :heavycheckmark: | :heavycheckmark: | | | :heavycheckmark: | | :x: | :x: | | | | :heavycheckmark: | :heavycheckmark: | | | :heavycheckmark: | | :heavycheckmark: | :heavycheckmark: | | | :heavycheckmark: | :x: | :heavycheckmark: | | | :heavycheckmark: | | :heavycheckmark: | :heavycheckmark: | | | :heavycheckmark: | :x: | :heavycheckmark: | | | :x: | | :x: | :heavycheckmark: | | | | :x: | :x: | | | :heavycheckmark: | | :x: | :heavycheckmark: | | | | :x: | :x: | | | :x: | | :x: | :x: | | | | :x: | :heavycheckmark: | | | :x: | | :x: | :x: | | | | :x: | :heavycheckmark: | | | :x: | | :x: | :heavycheckmark: | | | | :x: | :x: | | | :x: | | :x: | :heavycheckmark: | | | | :x: | :x: | | Proprietary Bindings | | | :x: | | :heavycheckmark: | :x: | | | | :x: | :x: | | | | | | | :x: | :heavycheckmark: | :heavycheckmark: | :heavycheckmark: | :x: | :x: | :heavycheckmark: | :heavycheckmark: | :heavycheckmark: | | Event Formats | | | :x: | | :x: | :x: | | | | :x: | :x: | | | :x: | | :heavycheckmark: | :heavycheckmark: | | | :heavycheckmark: | :heavycheckmark: | :heavycheckmark: | | | :x: | | :heavycheckmark: | :x: | | | | :x: | :x: | | Bindings / Content Modes | | | :x: | | :heavycheckmark: | :x: | | | | :x: | :x: | | | :x: | | :heavycheckmark: | :x: | | | | :x: | :x: | | | :x: | | :heavycheckmark: | :heavycheckmark: | | | :heavycheckmark: | :heavycheckmark: | :heavycheckmark: | | | :x: | | :heavycheckmark: | :heavycheckmark: | | | :heavycheckmark: | :heavycheckmark: | :heavycheckmark: | | | :x: | | :x: | :x: | | | | :heavycheckmark: | :heavycheckmark: | | | :x: | | :heavycheckmark: | :heavycheckmark: | | | :heavycheckmark: | :x: | :heavycheckmark: | | | :x: | | :heavycheckmark: | :heavycheckmark: | | | :heavycheckmark: | :x: | :heavycheckmark: | | | :x: | | :x: | :x: | | | | :x: | :x: | | | :x: | | :x: | :x: | | | | :x: | :x: | | | :x: |