From 054a095c0d248eacbc68ed3a621dfec2efc9ced5 Mon Sep 17 00:00:00 2001 From: Scott Nichols Date: Fri, 30 Aug 2019 11:31:12 -0700 Subject: [PATCH] Reword SDK.md to be more general. Signed-off-by: Scott Nichols --- SDK.md | 326 ++++++++++++++------------------------------------------- 1 file changed, 81 insertions(+), 245 deletions(-) diff --git a/SDK.md b/SDK.md index 0c23e428d..96d57166a 100644 --- a/SDK.md +++ b/SDK.md @@ -1,290 +1,126 @@ -# CloudEvents SDK Requirements - Version 0.4-wip +# CloudEvents SDK Requirements -The intent of this document to describe bare minimum set of requirements for a -new SDKs. - -## Status of this document - -Since [CloudEvent spec](spec.md) still considered as a working draft this -document also suppose to be considered as a working draft. - -## Contribution acceptance - -Being an open source community CloudEvents team is open for a new members as -well open to their contribution. In order to ensure that an SDK is going to be -supported and maintained CloudEvents community would like to ensured that: - -- a person (developer, committer) is going to become a maintainer -- a person commits to support ongoing changes to the [CloudEvent spec](spec.md) - -## Officially maintained software development kits (SDK) - -Software Development Kit (SDK) is a set of helpers designed and implemented to -enhance and speed up a CloudEvents integration. As part of community efforts -CloudEvents team committed to support and maintain the following SDKs: +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: +- [CSharp](https://github.com/cloudevents/sdk-csharp) - [Go SDK](https://github.com/cloudevents/sdk-go) - [Java SDK](https://github.com/cloudevents/sdk-java) -- [Python SDK](https://github.com/cloudevents/sdk-python) -- [CSharp](https://github.com/cloudevents/sdk-csharp) - [JavaScript SDK](https://github.com/cloudevents/sdk-javascript) +- [Python SDK](https://github.com/cloudevents/sdk-python) -## SDK contribution - -That's said, being an open source community CloudEvents is all about building -open for contribution. In order to keep the development/user experience the same -(as much as possible) CloudEvents team agreed to establish minimum requirements -for a new SDK. - -### Technical requirements - -Supports CloudEvents spec milestones and ongoing development version. HTTP -transport support (both structured and binary). Widely used programming language -version. - -### Preferable API signature guidelines - -In order to remain developer/user UX the same among existing officially -supported SDKs CloudEvents team asks maintainers to align with the following API -signatures. Please consider the following code as pseudo-code. - -#### Event object constructor API - -Event build considered to be an event constructor: - -``` - v01.Event() -``` - -#### Event object setters API - -This particular code sample represents bare minimum number of setters: - -``` - v01.Event(). - SetDataContentType("application/json"). - SetData('{"name":"john"}'). - SetEventID("my-id"). - SetSource("from-galaxy-far-far-away"). - SetEventTime("tomorrow"). - SetEventType("cloudevent.greet.you") -``` - -Content type setter represents an event MIME content type setter: - -``` - SetDataContentType(content_type string) -``` - -Data setter represents an event data setter: - -``` - SetData(event_data serializable) -``` - -ID setter represents an event ID setter: - -``` - SetEventID(id string) -``` - -Source setter represents an event source setter: - -``` - SetSource(source URL) -``` - -Time setter represents event emit time setter: - -``` - SetEventTime(time RFC3339) -``` - -Type setter represents an event type setter: - -``` - SetEventType(type string) -``` - -Extensions setter represents an event type setter: - -``` - SetExtensions(exts map[string]string) -``` - -Generic setter represents an event attribute setter: - -``` - Set(key string, value serializable) -``` - -#### Event object getters API - -Event getters are set of methods designed to retrieve an event attributes. -Here's the list of getters: - -``` - EventType() -> string - Source() -> URL - EventID() -> string - EventTime() -> RFC3339 - DataSchema() -> URL - DataContentType() -> string - Data() -> serializable - Extensions() -> map[string]string - - Get(key string) -> serializable - -``` - -All these getters correspond to setters from above. - -#### HTTP API +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. -CloudEvents spec defines an HTTP transport, that's said, SDK suppose to support -an HTTP transport routine. As part of an CloudEvent spec, defines two formats: +## Contribution Acceptance -- [structured](http-transport-binding.md#32-structured-content-mode) -- [binary](http-transport-binding.md#31-binary-content-mode) +Being an open source community CloudEvents team is open for a new members as +well open to their contributions. In order to ensure that an SDK is going to be +supported and maintained CloudEvents community would like to ensure that: -#### HTTP API unmarshaller +- Each SDK has active points of contact. +- Each SDK supports ongoing changes to the [CloudEvent spec](spec.md). -An HTTP unmarshaller should be capable of detecting a CloudEvent format from an -HTTP request headers and a body. Here's the signature of an unmarshaller: +## Technical Requirements -``` - FromRequest( - headers HTTP-Headers, - body Stream, - data_unmarshaller function(data serializable) -> object - ) -> CloudEvent: -``` +Each SDK MUST meet these requirements: -In this signature: +- 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 Conical Event. +- Idiomatic usage of the programming language. + - Using current language version(s). +- Supports HTTP transport renderings in both `structured` and `binary` + encodings. -- `headers` could be a `map of string to string` or a - `map of string to list of strings`, the type of this parameter may vary -- `body` is a stream, since CloudEvent spec does not define exact type of an - event data, SDK should not be responsible for data coercing -- `data_unmarshaller` is a function that performs data unmarshaller, logic of - this method may vary depending on the type of an event format -- the return statement is a CloudEvent of the particular spec +### Object Model Structure Guidelines -#### HTTP API marshaller +Each SDK will provide a generic CloudEvents class/object/structure that +represents the conical form of an Event. -An HTTP marshaller is a method that should be capable to convert a CloudEvent -into a combination of an HTTP request headers and a body. Here's the signature -of a marshaller: +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: ``` - ToRequest( - event CloudEvent, - converter_type FormatRef, - data_marshaller function(data serializable) -> object - ) -> map[string]string, Stream : +Event (-> Message) -> Transport ``` -In this signature: - -- `event` is a CloudEvent of the particular spec -- `converter_type` represents a type of an HTTP binding format - ([binary](http-transport-binding.md#31-binary-content-mode) or - [structured](http-transport-binding.md#32-structured-content-mode)) -- `data_marshaller` is a function that serialized an event data -- the return statement is a set of an HTTP headers and request body - -The reason for such signature is that in most of programming languages there are -a lot if different HTTP frameworks and route handling signature may vary, but -HTTP headers and a request body is common (or may be easily converted to the -appropriate type). - -#### HTTP Converters API - -Each transport binding unmarshaller/marshaller is a set of converters. In terms -of an SDK the converter is a set API methods that are actually converting a -CloudEvent of the particular spec into a transport binding-ready data. - -Converter API consists of at least two methods: +and ``` - Read(...) - Write(...) +Transport (-> Message) -> Event ``` -Signature of these methods may vary depending on the the type of a transport -binding. +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. -HTTP Converters API is the example of Converters API implementation for the -[HTTP transport binding](http-transport-binding.md). Taking into account that -the CloudEvent spec defines 2 (structured and binary) formats, an SDK suppose to -implement two converters (one per each format): +At a high level, the SDK needs to be able to help with the following tasks: -- `BinaryHTTPCloudEventConverter` -- `StructuredHTTPCloudEventConverter` - -HTTP Converters suppose to comply the following signature: - -``` - Read( - event CloudEvent, - headers headers HTTP-Headers, - body Stream, - data_unmarshaller function(data serializable) -> object - ) -> CloudEvent - - Write( - event CloudEvent, - data_marshaller function(data serializable) -> object - ) -> HTTP-Headers, Stream - -``` +1. Compose an Event. +1. Encode an Event given a transport and encoding (into a Transport Message if + appropriate). +1. Decode an Event given a transport specific message, request or response (into + a Transport Message if appropriate). -As you may see, Converter signature follows the signature of -marshaller/unmarshaller. It means that an HTTP marshaller/unmarshaller is a set -of binary and structured converters. +#### Compose an Event -In `Read`: +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` - a placeholder (empty event object), see - [event constructor](#event-object-constructor-api). -- `headers` - an HTTP request headers -- `body` - an HTTP request body -- `data_unmarshaller` - a function that turns an event data into an object of - the particular type -- returns a valid CloudEvent of the particular spec +1. Event Creation -In `Write`: +- "I have this data that is not formatted as a CloudEvent and I want it to be." -- `event` - a CloudEvent -- `data_marshaller` - a function that marshals an event data -- returns a set of an HTTP headers and a body. +1. Event Mutation -### AMQP API +- "I have a CloudEvents formatted Event and I need it to be a different Event." +- "I have a CloudEvents formatted Event and I need to mutate the Event." -#### AMQP marshaller/unmarshaller +Event creation is highly idiomatic to the SDK language. -TBA +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. -#### AMQP Converters API +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. -TBA +#### Encode/Decode an Event -### MQTT API +Each SDK will support encoding and decoding an Event with regards to a transport +and encoding. `Structured` encoding is the easiest to support, as it is just +`json`, but `Binary` is fairly custom for each transport. -#### MQTT marshaller/unmarshaller +#### Data -TBA +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. -##### MQTT Converters API +#### Extensions -TBA +Supporting CloudEvents extensions is idiomatic again, but a method that mirrors +the data access seems to work. -### NATS API +#### Validation -#### NATS marshaller/unmarshaller +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. -TBA +## Documentation -##### NATS Converters API +Each SDK must provide examples using at least HTTP transport of: -TBA +- Composing an Event. +- Encoding and sending a composed Event. +- Receiving and decoding an Event.