Why do you use a proprietary protocol & a client library

I don’t see how Zeebe with its proprietary protocol and its client library fits well in a microservice architecture with the goal of loosly coupling.
Why not just use a REST api and maybe Kafka? To need to distribute the client library in the same version to all microservices that implement worker services is a nightmare. Did I understand something wrong?

Hi @Beat, thanks for the questions. First, regarding the general use case: most users we talk to are interested in Zeebe because they’re looking for a way to get visibility into (& have more control over) business processes that span multiple microservices. This process-level oversight isn’t something you get by default when services are communicating via REST API or Kafka, and comparable tools for e.g. tracing often use a relatively small sample of data (meaning that not all process instances are accounted for) and don’t necessarily surface business process flows in a way that is easy to interpret. This is the “blank space” that Zeebe seeks to fill.

We’ve always done our best to make sure Zeebe can adhere to microservice principles like loose coupling. The Zeebe engine doesn’t execute any business logic and only stores the state of active workflow instances, and while it’s true that worker services will need to include a Zeebe client in order to request tasks from the engine and notify the engine when those tasks are complete, the services can be developed and deployed independently of one another and independently of the engine itself.

We use gRPC for communication between Zeebe clients and a Zeebe cluster, which we chose mostly because of a) performance and b) the ability to easily generate clients in a range of different programming languages. For minor releases, we’ll provide backward compatibility for clients so that you don’t have to update to a new version of a client every time you update to a new version of the Zeebe engine. gRPC would enable us to add support for a REST API, too, and it’s something that we are aware of but that we haven’t prioritized until we hear more user feedback about it. Some workarounds might be available, too, e.g. https://github.com/grpc-ecosystem/grpc-gateway

I’ll also mention that it’s possible to combine Zeebe with Kafka. We haven’t included an official connector in the project but we have started to explore this and wrote a bit about it here: https://zeebe.io/blog/2018/12/writing-an-apache-kafka-connector-for-zeebe/

Let me know if this helps to answer your questions. Happy to elaborate if I missed the mark on what you were asking or if I can provide more context. And if you have any general feedback about our approach, we are glad to hear it. It’s always helpful for us to get that input.


1 Like

Thanks for the detailed explanation! In our company we are approaching the “blank space” from the Saga pattern side with the idea of independent orchestrating microservices using Sagas to implement processes calling working services that don’t know and care about the process.
I ask myself if there could be a meaningful combination of our 2 approaches. The process microservices using zeebe for state handling with all its benefits, deploying its process definition on zeebe and acting as a “worker” adapter to our independent “working” services. But I’m not sure if something like that really make sense…

Hi @Beat, sure thing! If I understand correctly, it sounds like we’re similar in our approach and mindset. Throughout our docs, we use an e-commerce order sample process:

In this case, we actually think of Zeebe (where the model is deployed) as an “order microservice” in that its core business capability is keeping track / fulfillment of the end-to-end order–but none of the more granular business logic that’s specific to payment processing, inventory, or shipping should be a part of this order microservice. That logic should live instead in the different worker services that are responsible for each task in the workflow.

And like you said, the worker services that are responsible for each task don’t need to be aware of the process as a whole–only of the “job” (as we call it in Zeebe) that they need to complete and will request from Zeebe.

Does that make sense to you and align with how you’re thinking about this?


Yes and no :slight_smile: We would implement an order-service with the public interface to place orders, get current orders state, …
In our current implementation this service would be based on a lightweight state handling component and a component to reliable invoke the “worker” services by REST. The “worker” services must be idempotent (like yours I guess). We are thinking about streaming commands and result events instead of using REST. This would have the advantage that the command id would assure the idempotent processing directly.
Using zeebe I think we would use the order-service as interface to the process in zeebe and maybe as interface between zeebe and the worker services to avoid distributing the zeebe library allover as we normally relay on (at least defacto) standards. So zeebe would be more of a replacement of our simple internal saga implementation with a more powerful implementation.