Changelog for Zeebe client lib maintainers

Hi, my name is Josh Wulf, and I’m a Developer Advocate at Camunda by day, and maintainer of the Zeebe Node Client by night.

This post documents changes to the Node client library that arise from changes to the Zeebe broker.

If you maintain a client lib, you can check in here for changes to the Zeebe broker that impact client libs (and add comments about things that you find - yay community!).

1.4.0 (July 2021) - Camunda Cloud 1.1

The DNS schema for Camunda Cloud hosted has been extended to support regions. Clusters are now addressed as ${clusterId}.${clusterRegion} If your client has a builder or convenience method that takes only a clusterId and then constructs the URL, you will need to extend it to support a clusterRegion.

To maintain backward-compatibility in the type system, I am making it an optional property - with the default when it is absent set to bru-2, the only available region at the moment. For more details, see this issue.

1.0.0-alpha7 (April 2021)

Version 1.0.0-alpha7 of the Zeebe broker is out with a breaking change to the DeployProcess GRPC API. See this diff. YAML process models are out, and the GRPC protocol is changed to remove them.

1.0.0-alpha3 (March 2021)

The 1.0.0-alpha3 image is out on Docker Hub with the 1.0.0 breaking changes API.

I’ve released a 1.0.0-alpha.3 of Zeebe Node that works with it.

Coming Up (for 1.0.0?)

This branch contains a PR that renames workflowprocess everywhere in the API.

So DeployWorkflow becomes DeployProcess, and so forth. See here for the protocol file.

To get a Zeebe broker to test against, prior to alpha3 / rc1 (update: I’m expecting to see a release of these changes, in April 2021) you can check out and build the 6453-rename-workflow branch of Zeebe.

This one will - potentially - be a big one for your client lib, depending on how much you wrap the gRPC API. If you don’t wrap the API at all, then the impact on the client lib will be minimal (mostly docs and examples), but the impact on user code will be larger.

If you do wrap the API, you could deprecate the methods like CreateWorkflowInstance and map them to the new API method, in this case CreateProcessInstance. Or you could keep the same application API surface area.

I wouldn’t recommend keeping the old naming scheme on your client lib API surface and switching it internally for the gRPC calls, because documentation and examples will start to drift away from the language used in the community.

I am currently planning to do this with the Zeebe Node Client (work in progress in this branch):

  1. Create a semver breaking change release that adds the new methods to the API surface of the Node client, deprecates the old method names, and maps the deprecated methods to the new ones. This allows users to run their existing code against the new broker version by just depending on the new package, with no code changes to applications.
  2. Deprecated fields with old property names in objects like ActivatedJob. Add the new properties, and write a transformer to extend objects with the old properties, so that they can be consumed by legacy application code.
  3. Use the TopologyResponse gateway field to emit a meaningful message if a user tries to use the new package with an older broker.

Users attempting to run earlier package versions against a 1.0.0 broker will get some error message that I can’t control. I can’t see much that I can do about that. For future breaking changes, I’ll think about building in something to detect a major version change in the gateway version string and hinting to the user that they need an updated client lib package.

I could check for the latest version of the Zeebe Node client, and if there is a major version package that matches the broker gateway version, advise them to install that. I may not be able to go back in time and provide that ergonomic, but I can plan for it for the future.

1.0.0-alpha2 (so far)

YAML Process (workflow) definitions are removed, so it has been deprecated in the gateway protocol:

message WorkflowRequestObject {
  enum ResourceType {
    // FILE type means the gateway will try to detect the resource type
    // using the file extension of the name field
    FILE = 0;
    BPMN = 1; // extension 'bpmn'
    YAML = 2 [deprecated = true]; // extension 'yaml'; deprecated as of release 1.0

  // the resource basename, e.g. myProcess.bpmn
  string name = 1;
  // the resource type; if set to BPMN or YAML then the file extension
  // is ignored
  // As of release 1.0, YAML support was removed and BPMN is the only supported resource type.
  // The field was kept to not break clients.
  ResourceType type = 2 [deprecated = true];
  // the process definition as a UTF8-encoded string
  bytes definition = 3;


In Zeebe 0.26, the gateway protocol added PartitionBrokerHealth to the Partition information returned in a TopologyResponse:

message Partition {
  // Describes the Raft role of the broker for a given partition
  enum PartitionBrokerRole {
    LEADER = 0;
    FOLLOWER = 1;
    INACTIVE = 2;

  // Describes the current health of the partition
  enum PartitionBrokerHealth {
    HEALTHY = 0;
    UNHEALTHY = 1;

  // the unique ID of this partition
  int32 partitionId = 1;
  // the role of the broker for this partition
  PartitionBrokerRole role = 2;
  // the health of this partition
  PartitionBrokerHealth health = 3;

The TopologyResponse now includes the gateway version as a string. This is useful for emitting error hints for users if they are using the wrong version of the client lib for the broker. Anything before 0.26 should return undefined in this field, at least in Node.

message TopologyResponse {
  // list of brokers part of this cluster
  repeated BrokerInfo brokers = 1;
  // how many nodes are in the cluster
  int32 clusterSize = 2;
  // how many partitions are spread across the cluster
  int32 partitionsCount = 3;
  // configured replication factor for this cluster
  int32 replicationFactor = 4;
  // gateway version
  string gatewayVersion = 5;


In Zeebe 0.25, the gateway protocol changed slightly:

  • PublishMessageResponse got a field:
message PublishMessageResponse {
  // the unique ID of the message that was published
  int64 key = 1;
  • PartitionBrokerRole got an additional member, INACTIVE:
enum PartitionBrokerRole {
  LEADER = 0;

Thanks @jwulf for keeping that updated

1 Like