CloudEvents .NET SDK

repository·main·Indexed 43 days ago

https://github.com/cloudevents/sdk-csharp

A .NET (C#) SDK for implementing the CNCF CloudEvents v1.0 specification. It provides tools to create, encode, decode, and transport event data, with support for various event formats (such as JSON and Protobuf) and protocol bindings (such as HTTP).

Tokens
10.5K
Snippets
20
Records
43
Agent score
53%

What's inside CloudEvents

  1. Overview of the CloudEvents .NET SDK

    main

    The CloudNative.CloudEvents package is a .NET (C#) SDK for creating, encoding, decoding, sending, and receiving CNCF CloudEvents. It currently supports the CloudEvents v1.0 specification.

    To support specific event formats or protocol bindings (like HTTP), you should add additional CloudNative.CloudEvents.* packages to your project. Refer to the user guide for a full list of available extensions.

  2. Identify CloudEvents SDK package naming and versioning patterns

    main

    When looking for packages or tracking releases, note the following patterns used by the project:

    Release Tagging

    Releases are identified by a unified tag that covers all packages in the repository.

    • Tag Format: CloudNative.CloudEvents.All-[VERSION] (e.g., CloudNative.CloudEvents.All-2.0.0)
    • Release Title: All packages version [VERSION] (e.g., All packages version 2.0.0)

    Pre-release Sequence

    New or unstable packages follow a specific versioning progression before aligning with the main SDK:

    1. 1.0.0-alpha.[N]
    2. 1.0.0-beta.[N]
    3. [STABLE_VERSION] (e.g., 2.1.0)
  3. Use Protocol Bindings to transport CloudEvents

    main

    Protocol bindings handle the movement of CloudEvents across specific transport layers (like HTTP or Kafka). They provide methods to extract a CloudEvent from a transport message or populate a transport message with an existing CloudEvent.

    Content Modes

    Most bindings support two modes, often controlled via a ContentMode parameter:

    • Structured Mode: The entire CloudEvent (attributes and data) is placed in the message body. The format is determined by a CloudEventFormatter.
    • Binary Mode: CloudEvent attributes are placed in the protocol metadata (e.g., HTTP headers), and only the CloudEvent.Data is placed in the message body.

    Batch Mode

    Some bindings (like HTTP) support Batch Mode, where the message body contains multiple CloudEvents. Specific batch-handling methods are provided by the binding for this purpose.

  4. Implement a CloudEventFormatter

    main

    To extend the SDK with a custom event format, implement the CloudEventFormatter abstract type. This type augments the CloudEvent specification by allowing the CloudEvent.Data property to hold object references instead of just raw bytes. The formatter is responsible for serializing these objects into bytes during encoding and deserializing bytes back into objects during decoding.

    Implementations should be aware of different content modes:

    • Binary mode: Data is serialized as a sequence of bytes. General-purpose formatters should handle byte[] without modification and support strings based on the datacontenttype attribute.
    • Structured mode: The entire CloudEvent is serialized as a single payload. The formatter must follow the rules of the specific event format being implemented.
    • Batch mode: (Note: Batch content mode is not currently implemented in the SDK).

    Implementations should clearly document which content modes they support.

  5. Use extension methods for CloudEvent extension attributes in 2.x

    main
    In version 2.x, extension attributes no longer require implementing the ICloudEventExtension interface. Instead, all attributes are represented by the CloudEventAttribute type. The recommended pattern for providing extensions is to use C# extension methods and static properties on the CloudEvent class.
  6. Understanding the CloudNative.CloudEvents.Core namespace

    main

    The CloudNative.CloudEvents.Core namespace provides utility classes designed for developers implementing custom protocol bindings or event formatters.

    Note for consumers: If your goal is only to create or consume CloudEvents, you generally do not need to use the classes in this namespace. The methods in these static classes are intentionally not implemented as extension methods to prevent them from appearing in IntelliSense for standard event creation and consumption code.

  7. Use CloudEvent Formatters for serialization

    main

    In Structured Mode, a CloudEventFormatter (derived from the CloudEventFormatter abstract base class) determines how the event is represented in the message body. Formatters are also responsible for serializing the event's Data.

    Supported Formats

    • JSON: Provided by JsonEventFormatter in either CloudNative.CloudEvents.SystemTextJson or CloudNative.CloudEvents.NewtonsoftJson packages.
    • Avro: Provided by AvroEventFormatter in CloudNative.CloudEvents.Avro.
    • Protobuf: Provided by ProtobufEventFormatter in CloudNative.CloudEvents.Protobuf.

    JSON Formatter Variants

    JSON implementations provide two types of formatters:

    1. JsonEventFormatter: A general-purpose formatter.
    2. JsonEventFormatter<T>: A single-type formatter that automatically deserializes the event data to type T. This is ideal when the data is expected to be JSON-compatible.
  8. Understand the CloudEvents SDK versioning strategy

    main

    The CloudEvents C# SDK uses an "umbrella" versioning strategy to ensure compatibility across its ecosystem. Most packages (the core SDK and its satellite packages like CloudNative.CloudEvents.AspNetCore) share the same version number and are released simultaneously via a single GitHub release.

    Key Versioning Rules:

    • Unified Versioning: Most packages do not specify a version in their .csproj files; instead, they inherit a global version from src/Directory.Build.props.
    • Satellite Packages: Packages that depend on the core SDK are released together to prevent dependency mismatches.
    • Major Version Exceptions: If a satellite package requires a different major version (e.g., to support a new major version of a dependency like MQTTnet), it will use its own major version while keeping the minor and patch versions synchronized with the rest of the SDK.
    • Pre-release/Unstable Packages: New packages use 1.0.0 as a notional stable version during alpha/beta stages to avoid version conflicts with the current stable umbrella. They synchronize with the main umbrella version only once they become stable.
  9. Understanding Protocol Binding extensions

    main

    Protocol binding integration is provided via extensions that map a CloudEvent to and from specific protocol messages (e.g., an HTTP request or response).

    Important: These extensions do not manage security, credentials, or other transport-level headers. The application remains in full control of the client and is responsible for adding any necessary authentication or service-specific headers required to interact with a product or service.

  10. How to serialize and deserialize CloudEvents

    main

    Do not use standard object serializers like JSON.NET directly on the CloudEvent class. This will not result in a valid CloudEvent structure.

    To correctly serialize or deserialize a CloudEvent, you must use a CloudEventFormatter. For example, use JsonEventFormatter from the CloudNative.CloudEvents.NewtonsoftJson package to handle JSON-based CloudEvents.

  11. General purpose vs single-type event formatters

    main

    When designing a formatter, you can choose between two patterns:

    1. General purpose formatters: Designed to handle any kind of CloudEvent data with reasonable, well-documented behavior (e.g., JsonEventFormatter). They use the datacontenttype to decide how to deserialize data.
    2. Single-type formatters: Typically generic types (e.g., JsonEventFormatter<T>) that are explicitly designed to handle a specific target type. They expect the Data property to be of type T and may ignore the datacontenttype. They must still support CloudEvents with null Data properties.

    Example: JsonEventFormatter<PubSubMessage> will throw an IllegalCastException if asked to serialize a CloudEvent where Data is a StorageEvent.