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

CloudEvent JSON Autocompletion without Class Wrapper #184

Closed
grant opened this issue May 22, 2020 · 1 comment · Fixed by #194
Closed

CloudEvent JSON Autocompletion without Class Wrapper #184

grant opened this issue May 22, 2020 · 1 comment · Fixed by #194

Comments

@grant
Copy link
Member

grant commented May 22, 2020

As a developer, I want to be able to have autocompletion for objects without having a wrapper class such as CloudEvent.

JavaScript objects are normal in Node development, and are preferred over classes.

image

EXPECTED:

import {CloudEvent} from 'cloudevents/v1';
const ce = {
    "specversion" : "1.0",
    "type" : "com.github.pull.create",
    "source" : "https://github.com/cloudevents/spec/pull",
    "subject" : "123",
    "id" : "A234-1234-1234",
    "time" : "2018-04-05T17:31:00Z",
    "comexampleextension1" : "value",
    "comexampleothervalue" : 5,
    "datacontenttype" : "text/xml",
    "data" : "<much wow=\"xml\"/>"
}: CloudEvent;
ce.

ACTUAL:

import {CloudEvent} from 'cloudevents/v1';
const ce = new CloudEvent({
    "specversion" : "1.0",
    "type" : "com.github.pull.create",
    "source" : "https://github.com/cloudevents/spec/pull",
    "subject" : "123",
    "id" : "A234-1234-1234",
    "time" : "2018-04-05T17:31:00Z",
    "comexampleextension1" : "value",
    "comexampleothervalue" : 5,
    "datacontenttype" : "text/xml",
    "data" : "<much wow=\"xml\"/>"
});
ce.

Note: The : CloudEvent can be dropped off from user code and be inferred with normal usage if the developer doesn't like TypeScript.

Advantages

  • Minus one level of indirection (no required Classes/Objects).
  • Better devX: Creating new CloudEvent(), new CloudEvent(), over and over is tedious and one more level of indirection. It's much easier to use JSON. I think most Node developers would agree.
  • Support common JS features: You can't combine 2 CloudEvent JSON payloads easily, but you can with 2 JavaScript objects ({ ...ce1, ...ce2}).
  • Performance: JS Class wrappers for JSON creates unnecessary constructors to be called. Simply not requiring a class can help.
  • Use raw JSON over JS Classes. (It's easier to copy/paste a CloudEvent into source code without wrapping it.

Disadvantages

  • Requires 1 .ts file in the source code of this repo. We generate all the other .ts files, but we can't generate this one no matter how hard we try.

How can we add this feature?

Related but not the same: #169

@grant
Copy link
Member Author

grant commented May 22, 2020

To get this feature with the use of raw object, I suggest we have 1 .ts file that would have the following below.

No other files would need to be .ts files.

/**
 * The object interface for CloudEvents 1.0.
 * @see https://github.com/cloudevents/spec/blob/v1.0/spec.md
 */
export interface CloudEvent1 {
  // REQUIRED Attributes
  /**
   * [REQUIRED] Identifies the event. Producers MUST ensure that `source` + `id`
   * is unique for each distinct event. If a duplicate event is re-sent (e.g. due
   * to a network error) it MAY have the same `id`. Consumers MAY assume that
   * Events with identical `source` and `id` are duplicates.
   * @required Non-empty string. Unique within producer.
   * @example An event counter maintained by the producer
   * @example A UUID
   */
  id: string;
  /**
   * [REQUIRED] Identifies the context in which an event happened. Often this
   * will include information such as the type of the event source, the
   * organization publishing the event or the process that produced the event. The
   * exact syntax and semantics behind the data encoded in the URI is defined by
   * the event producer.
   * Producers MUST ensure that `source` + `id` is unique for each distinct event.
   * An application MAY assign a unique `source` to each distinct producer, which
   * makes it easy to produce unique IDs since no other producer will have the same
   * source. The application MAY use UUIDs, URNs, DNS authorities or an
   * application-specific scheme to create unique `source` identifiers.
   * A source MAY include more than one producer. In that case the producers MUST
   * collaborate to ensure that `source` + `id` is unique for each distinct event.
   * @required Non-empty URI-reference
   */
  source: string;
  /**
   * [REQUIRED] The version of the CloudEvents specification which the event
   * uses. This enables the interpretation of the context. Compliant event
   * producers MUST use a value of `1.0` when referring to this version of the
   * specification.
   * @required MUST be a non-empty string.
   */
  specversion: string;
  /**
   * [REQUIRED] This attribute contains a value describing the type of event
   * related to the originating occurrence. Often this attribute is used for
   * routing, observability, policy enforcement, etc. The format of this is
   * producer defined and might include information such as the version of the
   * `type` - see
   * [Versioning of Attributes in the Primer](primer.md#versioning-of-attributes)
   * for more information.
   * @required MUST be a non-empty string
   * @should SHOULD be prefixed with a reverse-DNS name. The prefixed domain dictates the
   *   organization which defines the semantics of this event type.
   * @example com.github.pull.create
   * @example com.example.object.delete.v2
   */
  type: string;

  /**
   * The following fields are optional.
   */

  /**
   * [OPTIONAL] Content type of `data` value. This attribute enables `data` to
   * carry any type of content, whereby format and encoding might differ from that
   * of the chosen event format. For example, an event rendered using the
   * [JSON envelope](./json-format.md#3-envelope) format might carry an XML payload
   * in `data`, and the consumer is informed by this attribute being set to
   * "application/xml". The rules for how `data` content is rendered for different
   * `datacontenttype` values are defined in the event format specifications; for
   * example, the JSON event format defines the relationship in
   * [section 3.1](./json-format.md#31-handling-of-data).
   */
  datacontenttype?: string;
  /**
   * [OPTIONAL] Identifies the schema that `data` adheres to. Incompatible
   * changes to the schema SHOULD be reflected by a different URI. See
   * [Versioning of Attributes in the Primer](primer.md#versioning-of-attributes)
   * for more information.
   * If present, MUST be a non-empty URI.
   */
  dataschema?: string;
  /**
   * [OPTIONAL] This describes the subject of the event in the context of the
   * event producer (identified by `source`). In publish-subscribe scenarios, a
   * subscriber will typically subscribe to events emitted by a `source`, but the
   * `source` identifier alone might not be sufficient as a qualifier for any
   * specific event if the `source` context has internal sub-structure.
   *
   * Identifying the subject of the event in context metadata (opposed to only in
   * the `data` payload) is particularly helpful in generic subscription filtering
   * scenarios where middleware is unable to interpret the `data` content. In the
   * above example, the subscriber might only be interested in blobs with names
   * ending with '.jpg' or '.jpeg' and the `subject` attribute allows for
   * constructing a simple and efficient string-suffix filter for that subset of
   * events.
   *
   * If present, MUST be a non-empty string.
   * @example "https://example.com/storage/tenant/container"
   * @example "mynewfile.jpg"
   */
  subject?: string;
  /**
   * [OPTIONAL] Timestamp of when the occurrence happened. If the time of the
   * occurrence cannot be determined then this attribute MAY be set to some other
   * time (such as the current time) by the CloudEvents producer, however all
   * producers for the same `source` MUST be consistent in this respect. In other
   * words, either they all use the actual time of the occurrence or they all use
   * the same algorithm to determine the value used.
   * @example "2020-08-08T14:48:09.769Z"
   */
  time?: Date | string;
  /**
   * [OPTIONAL] The event payload. This specification does not place any restriction
   * on the type of this information. It is encoded into a media format which is
   * specified by the datacontenttype attribute (e.g. application/json), and adheres
   * to the dataschema format when those respective attributes are present.
   */
  // tslint:disable-next-line:no-any
  data?: any | string | number | boolean | null;
  /**
   * [OPTIONAL] CloudEvents extension attributes.
   */
  // tslint:disable-next-line:no-any
  [key: string]: any;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant