The protos within this directory hierarchy represent the data within events generated by Google eventing infrastructure, usually represented as the data attribute within a CloudEvent. They are provided as machine-readable schemas, allowing libraries of data types to be created to make it easier to consume events.
There are two protobuf messages that are relevant for any given CloudEvent type:
- The "envelope" message (e.g.
ObjectFinalizedEvent
) representing the complete CloudEvent, including any extension attributes. - The "data" message (e.g.
StorageObjectData
)
There is a 1:1 relationship between CloudEvent types and envelope
messages, but a many:1 relationship between CloudEvent types and
data messages. In other words, many CloudEvent types can use the
same data message. For example, every event associated with
something happening to a Cloud Storage object uses StorageObjectData
as the data message. Each envelope message specifies the CloudEvent
type it's associated with via a proto annotation.
Initially we will generate libraries that only contain the data messages. The event messages serve as useful documentation for the event type strings and extension attributes. They will be included in the libraries at a later date if that proves useful.
Note that each proto package is versioned, but this version is independent of any API version. It would be possible for a single API version to support multiple event versions, or vice versa.
Our convention for event types is to have a dot-separated list of the following values, in the order:
google
(always)- product (e.g.
firebase.auth
orcloud.storage
) - resource (e.g.
object
ordocument
) - version (e.g.
v1
) - action (e.g.
finalized
ordeleted
)
The "action" is the action that causes the event to be emitted.
The proto package (in the package
part of each .proto file) must
be google.events.
product.
version. The .proto files should be
in a directory structure where each element of the package name
corresponds to a directory. The envelope messages must be in a file
named events.proto
, and the data messages (including any messages
they refer to) must be in a file named data.proto
. The purpose of
this separation is to allow the envelope and data messages to coexist,
but for consumer libraries to be generated that only contain the data
messages.
As a complete example, consider the event that is created when a Google Cloud Storage object is finalized:
- Proto files:
google/events/cloud/storage/v1/events.proto
andgoogle/events/cloud/storage/v1/data.proto
- Envelope message:
google.events.cloud.storage.v1.ObjectFinalizedEvent
- Data message:
google.events.cloud.storage.v1.StorageObjectData
- Event type:
google.cloud.storage.object.v1.finalized
Note that the events
part of the proto package is not part of the
CloudEvent type, for brevity. It's included in the proto package to
distinguish event message from those used in APIs.
Additionally, the version and resource parts deliberately appear in different orders between fully-qualified message name and CloudEvent type. That reversal may seem confusing initially, but it means that events for multiple resources in the same product (e.g. buckets and objects within Cloud Storage) can use common messages in their definitions.
The product and version parts must be all lower-case to conform with
proto package naming conventions. A product may consist of multiple
segments (e.g. cloud.storage
) but if a single segment consists of
multiple words, they should be simply lower-cased. For example,
firebase.remoteconfig
is the product name for Firebase Remote
Config. In this case, the csharp_namespace
option (and similar for
other languages that generate code from the protos) should be set to
indicate the correct word separation via casing.
The resource and action parts are not included in the proto package, so have more flexibility. Multi-word segments should be camel-cased. Full examples of CloudEvent types that involve camel-cased segments include:
google.cloud.storage.object.v1.metadataUpdated
google.firebase.remoteconfig.remoteConfig.v1.updated
While not required for technical correctness, we use a suffix of "Event"
for all envelope messages, and a suffix of "Data" for all event data messages.
Sometimes it can be convenient to combine the two suffixes. For example,
DocumentEventData
in the Firestore package is used as the event data
message for all document events. This approach should only be taken
when it is required for clarity.
We avoid the use either "Event" or "Data" as a suffix for messages which aren't envelope messages or event data messages.
While not a strict technical necessity, governance rules will
strongly encourage all event types for a single resource to create a
new version at the same time: if there's a need for
google.cloud.storage.object.v2.finalized
, then all the other
object-related event types (deleted
etc) should be available as
v2
events as well. However, other resources in the same product do
not have to take a new version. This allows users to write common
code to handle all events for a single resource, without creating
unnecessary churn when only an unrelated resource type needs
a new version. (If your code only consumes bucket.v1
events, the
introduction of object.v2
events should not affect you.)
CloudEvent providers may include additional data fields beyond those documented here. In particular:
- Some events may include fields with legacy names such as
message_id
for compatibility purposes. - Event providers using proto3 JSON formatting of protobuf
Any
messages may include a field called@type
as a natural artifact of that formatting process.
Neither of these should concern consumers: it's always possible that new fields will have been added to CloudEvents between the time at which the code was built and deployed, and the time at which the CloudEvent is received. Consumers must therefore handle unexpected data fields. This note is primarily to expain some likely causes of unexpected fields to avoid developer confusion.