-
Notifications
You must be signed in to change notification settings - Fork 19
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
ADR for usage of gRPC for networking between services #479
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,125 @@ | ||||||
--- | ||||||
adr: "0024" | ||||||
status: Proposed | ||||||
date: 2024-11-20 | ||||||
tags: [server, architecture, communication] | ||||||
--- | ||||||
|
||||||
# 0024 - Adopting gRPC for Inter-Service Communication | ||||||
|
||||||
<AdrTable frontMatter={frontMatter}></AdrTable> | ||||||
|
||||||
## Context and Problem Statement | ||||||
|
||||||
As Bitwarden's microservices architecture continues to evolve, the need for efficient, reliable, and | ||||||
performant inter-service communication becomes increasingly critical. Our current REST-based API | ||||||
communication model, while functional, may not be optimal for all types of service-to-service | ||||||
interactions, especially as we scale and introduce more complex, high-throughput operations. | ||||||
|
||||||
We need to evaluate whether adopting gRPC for inter-service communication could provide benefits in | ||||||
terms of performance, type safety, and developer productivity. | ||||||
|
||||||
### What is gRPC and why is it beneficial? | ||||||
|
||||||
gRPC (gRPC Remote Procedure Call) is an open-source framework developed by Google for efficient and | ||||||
fast inter-service communication. It offers several advantages over traditional REST APIs and other | ||||||
HTTP/1.1 technologies: | ||||||
|
||||||
1. **Performance**: gRPC uses Protocol Buffers as its interface definition language and binary | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. โ๏ธ These don't need to be numbered; just use bullets. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Like the considered options, dash these. |
||||||
serialization format, resulting in smaller payload sizes and faster processing compared to | ||||||
text-based serialization formats like JSON or XML. | ||||||
|
||||||
2. **HTTP/2 Support**: gRPC leverages HTTP/2, which provides features like multiplexing, header | ||||||
compression, and bidirectional streaming, leading to improved network utilization and reduced | ||||||
latency. | ||||||
|
||||||
3. **Strong Typing**: With Protocol Buffers, gRPC provides strong typing for request and response | ||||||
objects, reducing errors and improving developer productivity. | ||||||
|
||||||
4. **Code Generation**: gRPC automatically generates client and server code, simplifying development | ||||||
and ensuring consistency across different languages and platforms. | ||||||
|
||||||
5. **Streaming**: gRPC not only supports unary RPCs, but also natively supports server-to-client | ||||||
streaming, client-to-server streaming, and bidirectional streaming, allowing for more efficient | ||||||
real-time communication between services. | ||||||
|
||||||
6. **Language Agnostic**: gRPC supports multiple programming languages, making it easier to build | ||||||
polyglot microservices architectures, if desired. | ||||||
|
||||||
7. **Deadline/Timeout Propagation**: gRPC has built-in support for deadline propagation and request | ||||||
cancellation, improving system resilience and resource management. | ||||||
|
||||||
These benefits, and others not mentioned, make gRPC particularly well-suited for microservices | ||||||
architectures, high-performance systems, and scenarios requiring real-time communication between | ||||||
services. | ||||||
|
||||||
## Considered Options | ||||||
|
||||||
- **Maintain current REST-based communication** - Continue using REST APIs for all inter-service | ||||||
communication. | ||||||
- **Adopt gRPC for all inter-service communication** - Completely replace REST with gRPC for all | ||||||
service-to-service interactions. | ||||||
- **Hybrid approach** - Implement gRPC for all new services while maintaining existing solutions. | ||||||
- **Evaluate alternative RPC frameworks** - Consider other RPC frameworks like Apache Thrift or | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ๐ญ This is really what the ADR is about. While we often have a proposed solution when the ADR is written, gRPC is explained above before options are even laid out. What I'd like to see adjusted here is to move the gRPC content below and into the decision outcome as well as pros and cons. These additional RPC frameworks should be listed as options, with the decision outcome explaining why they were not a good fit. Your background above shouldn't be anything about gRPC but the problem at hand and desire to optimize the channel, security, etc. generically and not aligned with a specific choice. |
||||||
Apache Avro. | ||||||
|
||||||
## Decision Outcome | ||||||
|
||||||
Chosen option: **Hybrid approach - Implement gRPC for all new services while maintaining REST for | ||||||
existing ones**. | ||||||
|
||||||
This approach allows us to leverage the benefits of gRPC for future development without the need to | ||||||
immediately refactor existing services, providing a gradual transition path. This leaves us the | ||||||
flexibility to refactor existing services to gRPC as needed, while also providing a path for gradual | ||||||
migration and new development. | ||||||
|
||||||
### Positive Consequences | ||||||
|
||||||
- Improved performance and efficiency for all new services due to gRPC's binary serialization and | ||||||
HTTP/2 support. | ||||||
- Simplifies contracts between services due to gRPC's usage of Protocol Buffers as the interface | ||||||
definition language and serialization format. | ||||||
- Enhanced type safety and contract-first development with Protocol Buffers for new services. | ||||||
- Better support for streaming in new services, enabling more real-time features. | ||||||
- Gradual adoption allows for learning and adjustment without disrupting existing systems. | ||||||
|
||||||
### Negative Consequences | ||||||
|
||||||
- Increased complexity in the system architecture with two communication protocols. | ||||||
- Slight learning curve for developers to become proficient with gRPC and Protocol Buffers. | ||||||
- Additional tooling and infrastructure required to support both gRPC and REST. | ||||||
- Inconsistency in communication protocols across the architecture during the transition period. | ||||||
- While Android, iOS, and Rust, all support gRPC, browser support is currently limited for gRPC. If | ||||||
we want a future reality where we primarily use gRPC, we'll likely still need a RESTful, HTTP/1 | ||||||
based API gateway for browsers to route requests to downstream gRPC services. | ||||||
|
||||||
### Plan | ||||||
|
||||||
1. Establish guidelines and best practices for implementing gRPC in new services. | ||||||
2. Develop a proof-of-concept implementation for the next planned service. | ||||||
3. Create comprehensive documentation and training materials for the development team on gRPC and | ||||||
Protocol Buffers. | ||||||
4. Implement gRPC for all new services moving forward. | ||||||
5. Develop strategies for efficient communication between gRPC and REST services during the | ||||||
transition period. | ||||||
6. Implement monitoring and observability solutions that support both gRPC and REST traffic. | ||||||
7. Evaluate the impact and benefits after implementing several new services with gRPC. | ||||||
8. Consider a long-term plan for gradually migrating existing REST services to gRPC based on the | ||||||
success of new implementations. | ||||||
|
||||||
## Additional Considerations | ||||||
|
||||||
- Ensure compatibility with our current C# server-side codebase and tooling for both REST and gRPC | ||||||
implementations. | ||||||
- Adapt our CI/CD pipelines and testing strategies to accommodate both REST and gRPC services. | ||||||
- Evaluate the implications for our SDK written in Rust and plan for potential updates to support | ||||||
gRPC. | ||||||
- Consider the opportunities for our mobile clients to adopt gRPC for client-server communication. | ||||||
- Assess the impact on our self-hosted instances and ensure they can support both communication | ||||||
protocols. | ||||||
- Consider the implications for external integrations and develop strategies to support both REST | ||||||
and gRPC interfaces as needed. | ||||||
|
||||||
This decision allows for a gradual adoption of gRPC while maintaining stability in existing | ||||||
services. We will continuously evaluate the effectiveness of this approach and adjust our strategy | ||||||
as necessary. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
๐จ Please drop any and all references to "microservices" in favor of "service-oriented architecture" or just "services".