-
Notifications
You must be signed in to change notification settings - Fork 23
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
Payload and Versioning #40
Comments
Thanks @xibz - this is really useful feedback!
The CloudEvents spec, and consequently the CDEvents one, support multiple transport bindings, including HTTP, MQTT, NATS and kafka. The format you included in there matches the structured content mode of the HTTP binding in CloudEvents. For CDEvents we don't have to prescriptive of the mode, but until now we have used binary content mode which matches with what you describe below, and is the default mode in the CloudEvents SDKs. Further to this, the CDEvents binding to CloudEvents is being discussed in #35. POST /someresource HTTP/1.1
Host: cdevents.example.com
ce-specversion: 1.0
ce-type: dev.cdevents.taskrun.started
ce-time: 2022-06-14T03:56:24Z
ce-id: 1234-1234-1234
ce-source: /staging/tekton/
ce-subject: /namespace/taskrun-123
Content-Type: application/json; charset=utf-8
Content-Length: nnnn
{
"meta" : {
"version" : "draft",
"timestamp" : "2022-06-14T03:50:24Z"
},
"subject": {
"id": "/namespace/taskrun-123",
"type: "taskrun",
"content": {
"task": "my-task",
"URL": "/apis/tekton.dev/v1beta1/namespaces/default/taskruns/my-taskrun-123"
"pipelinerun": {
"id": "/somewherelse/pipelinerun-123",
"source": "/staging/jenkins/"
}
}
},
"extensions": [{}], // documented extensions could go here
"payload": // free form nested data goes here
}
This is a very good point. Services that already send CloudEvents could send CDEvents to existing consumers and they would still be able to parse the message (until they are ready to take advantage of CDEvents). This approach matches what we implemented in the SDKs for now and what we used in the initial POC, with the only difference that we used multiple CloudEvents extensions, one for each piece of data from the CDEvents spec. The disadvantages of this approach that I can see are:
I think this might be difficult. You would still need a root element, and that would have to be the one from the original payload, if we want backward compatibility. However, the CDEvents SDK would not be able to parse the root element of the payload anymore. One way around the issue could be to have an
My proposal would be include in the SDKs a mode that allows keeping all CDEvents data in headers, but defaulting to a CDEvents payload which includes a
|
@xibz About versioning, I totally agree we should find an answer for the questions you're posing. I would like to keep the discussion about that in a separate issue to avoid crossing threads of discussion. I'd be happy to copy that part in a new issue unless you'd prefer to do it yourself. |
@xibz is the implementation of |
@xibz I will close this for now. Feel free to re-open or create a new issue if there is still something that needs to be addressed. |
I attended cdCon this week, and had a lovely chat with @afrittoli and wanted to highlight a couple issues we discussed.
Format
Currently the spec makes payload a nested object, but it NEEDs to be a first class citizen. The reason for this is anyone adopting this spec would have to break all their customers using their service that may or may not be following the spec. Further, anything that uses plugins, grpc, or something similar would be completely broken by the current standard. This is a non-starter for anyone who ensures they are never any breaking changes to their customers, ie AWS, Google, Azure.
I propose three alternative approaches.
Headers
What the spec currently has is this
So instead we'd have headers,
X-CloudEvents-Id
for example. This makes the payload unchanged, which is huge for any end user. Looking at logs as well as other things remains unchanged otherwise these changes may surprise a user and break a user especially if they are doing anything with those logs, like log parsing.And now our example above looks like
The
X-CloudEvents-Metadata
would act as any custom key values needed by the service. The header format offoo=bar; baz=qux
is widely used in HTTP headers when multiple key values are needed within a header. See Strict-Transport-Security.The major benefits with going with this approach is the payload is COMPLETELY untouched and thus making completely backwards compatible with any pre-existing service.
Payload and Metadata
Another approach is to make pre-existing payloads that customers have a first class citizen, as in making that untouched, and adding a field within the payload that would house all the event information.
Hybrid
In this approach we use headers as well as a new cloud events field. Things like
X-CloudEvents-Id
could be a header, and the customer exclusive data likecomexampleextension1
could be in the payload field.Versioning
I know none of this is currently in the spec/standard, but I definitely think it's worth discussing. Basically how do you version and support interoperability between all the possibilities?
For instance, some service A could be on version 1, and some service B could be on version 2. Are major versions always going to be backwards compatible, so sending requests between these services should always work?
Further, types have to have a version as well. The
com.github.pull_request.opened
type may have a completely different payload years later. That adds a whole layer of complexity... In addition, adding a new type to the spec would have to be a major version bump of the spec, since anyone using version 1.x and 1.y adds a new type, then 1.x will have no idea on how to deal with that.How does major versioning look like with interoperability? Does EVERY service need to update to the new major version? How do we plan on handling that???
The text was updated successfully, but these errors were encountered: