dapr / dapr/java-sdk

[proposal]better control http and grpc related dependencies

Open
#785 4 comments 5 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
300
Forks
230
Avg merge
1d 20h
Merged PRs (30d)
4

Description

## background

Since we have HTTP API and gRCP API in dapr, in Dapr Java sdk project, we both have some dependencies to support Dapr HTTP API and Dapr gRPC API:

- sdk-autogen project: depends on grpc-netty-shaded / grpc-protobuf / grpc-stub for Dapr gRPC API

```xml

io.grpc
grpc-netty-shaded
${grpc.version}
runtime


io.grpc
grpc-protobuf
${grpc.version}


io.grpc
grpc-stub
${grpc.version}

```

- Sdk project: depends on okhttp and jackson for Dapr HTTP API

```xml

com.fasterxml.jackson.core
jackson-databind
2.12.6.1


com.squareup.okhttp3
okhttp
4.9.0

```

and also depends on dapr-sdk-autogen for Dapr gRPC API:

```xml

io.dapr
dapr-sdk-autogen
${project.version}

```

In dapr java sdk project, now we don't have fine-grained dependency control and all the subprojects are depend on each other simply. So for each application, whether it depends on the sdk/sdk-springboot/sdk-actors project, it will end up depending on all the http and grpc dependencies:

![dependencies](https://user-images.githubusercontent.com/1582369/191151409-c6b50ea7-949b-4abb-add1-391b201e22db.png)

## Problems

The problem is that the developers will find that both HTTP and gRPC related dependencies are included in the application's classpath even only HTTP API or gRPC API is used. It will introduce unnecessary dependencies into application and make the package more bigger.

A more serious problem is that these dependencies increase the probability of dependency conflicts. An unused dependency causing a dependency conflict... It doesn't make sense.

In critical projects, dependencies are often required to be reviewed. Introducing dependencies that are not used will be challenged.

To exclude some transitive dependencies, the developers have to set `exclusions` when they use the dependencies. For example, to introduce dapr sdk without gRPC API support:

```xml

io.dapr
dapr-sdk
${project.version}


io.dapr
dapr-sdk-autogen



```

Or to introduce dapr sdk without http API support:

```xml

io.dapr
dapr-sdk
${project.version}


com.fasterxml.jackson.core
jackson-databind


com.squareup.okhttp3
okhttp



```

This is not friendly to devepers and easy to make mistakes.

## Proposal

### split into http and gRPC parts

To better control http and gRPC related dependencies and NOT introduce unnecessary dependencies into Daprd based Java applications, I suggest to clearly split http and gRPC dependencies, so that users can explicitly choose to use either http or gRPC, or both if necessary.

![sdk-split](https://user-images.githubusercontent.com/1582369/191152066-cfe9eb5a-20a0-4543-a61f-f3676e100158.png)

We should split sdk project into three new projects:

- sdk-grpc: include all the code for Dapr gRPC API and depends on sdk-autogen
- sdk-http: include all the code for Dapr HTTP API
- sdk-common: include common code for sdk-grpc and sdk-http
- sdk: current code will move into sdk-grpc and sdk-http projects, keep this sdk for backward compatible or we can mark it as "deprecated" and remove it later safely.

Similarly, other projects like sdk-actors and sdk-springboot need to be split in this way:

![sdk-actor-springboot-split](https://user-images.githubusercontent.com/1582369/191152100-e924bc43-937f-46ac-ac5c-98c8e03903f8.png)

### how to use dapr java sdk

To use only dapr http api, the applications should depends on sdk-springboot-http / idk-actors-http / sdk-http :

![use-http](https://user-images.githubusercontent.com/1582369/191152129-2766d279-29d7-4457-a524-af6910c9242c.png)

To use only dapr gRPC api, the applications should depends on sdk-springboot-grpc / idk-actors-grpc / sdk-grpc :

![use-grpc](https://user-images.githubusercontent.com/1582369/191152150-b1be1ff4-95b4-4956-bdde-4db6454497f3.png)

For legacy applications which use dapr java sdk before this proposal, they can continue to depends on sdk-springboot / sdk-actors / sdk :

![use-legacy](https://user-images.githubusercontent.com/1582369/191152171-b3873061-9917-4f8a-b3b7-51df6fb78f88.png)

In particular, if the applications really need to use both HTTP API and gRPC API, suggest to use both sdk-xxx-http and sdk-xxx-grpc, since we will mark sdk-springboot / sdk-actors / sdk as "deprecated" and plan to remove them in the future.

### default behavior of dapr java sdk

In dapr java sdk, gRPC client is used by default for all building blocks but except service invoke: HTTP client will be used for service invoke by default.

See the source code in class `DaprClientBuilder` in sdk project:

```java
public DaprClientBuilder() {
......
this.apiProtocol = Properties.API_PROTOCOL.get();
this.methodInvocationApiProtocol = Properties.API_METHOD_INVOCATION_PROTOCOL.get();
this.daprHttpBuilder = new DaprHttpBuilder();
}

private static final DaprApiProtocol DEFAULT_API_PROTOCOL = DaprApiProtocol.GRPC;
private static final DaprApiProtocol DEFAULT_API_METHOD_INVOCATION_PROTOCOL = DaprApiProtocol.HTTP;
```

Since we split http and grpc in this proposal, the default behaviro should update to:

- In sdk-xxx-http projects, suggest to change the default behavior to use http client for all building blocks
- In sdk-xxx-grpc projects, suggest to change the default behavior to use grpc client for all building blocks

And we need to discuss and make decision that should we keep the default behavior of current dapr java sdk: use both grpc and http (only for service invoke).

### keep class name and package name

For backward compatible, when we split the sdk-XXX project into sdk-XXX-http / sdk-XXX-grpc / sdk-XXX-common, we should keep curernt class name and pacakge name, especially for PUBLIC class.

When developers update the version of Dapr Java sdk to the new version with this proposal is included, they only need to change the name of the dependencies and don't need to change the code (at least they don't need to change too many code).

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.