Skip to content

Commit b7550aa

Browse files
feat(): Bring your Own Proto Support (#298)
* Implementation of bring your own proto Signed-off-by: Xavier Geerinck <[email protected]> * WIP on example for Bring your own proto Signed-off-by: Xavier Geerinck <[email protected]> * This went missing somehow Signed-off-by: Xavier Geerinck <[email protected]> * Update interface for proxy creation Signed-off-by: Xavier Geerinck <[email protected]> * Resolve merge issue Signed-off-by: Xavier Geerinck <[email protected]> * Make index copy clearer by giving it a name and linting fix Signed-off-by: Xavier Geerinck <[email protected]> * Work on comments Signed-off-by: Xavier Geerinck <[email protected]>
1 parent 7cf5c32 commit b7550aa

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+4495
-59
lines changed

daprdocs/content/en/js-sdk-docs/js-client/_index.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,34 @@ dapr run --app-id example-sdk --app-protocol grpc -- npm run start
7777
npm run start:dapr-grpc
7878
```
7979

80+
## Proxying Requests
81+
82+
By proxying requests, we can utilize the unique capabilities that Dapr brings with its sidecar architecture such as service discovery, logging, etc., enabling us to instantly "upgrade" our gRPC services. This feature of gRPC proxying was demonstrated in [community call 41](https://www.youtube.com/watch?v=B_vkXqptpXY&t=71s).
83+
84+
### Creating a Proxy
85+
86+
To perform gRPC proxying, simply create a proxy by calling the `client.proxy.create()` method:
87+
88+
```javascript
89+
// As always, create a client to our dapr sidecar
90+
// this client takes care of making sure the sidecar is started, that we can communicate, ...
91+
const clientSidecar = new DaprClient(daprHost, daprPort, CommunicationProtocolEnum.GRPC);
92+
93+
// Create a Proxy that allows us to use our gRPC code
94+
const clientProxy = await clientSidecar.proxy.create<GreeterClient>(GreeterClient);
95+
```
96+
97+
We can now call the methods as defined in our `GreeterClient` interface (which in this case is from the [Hello World example](https://github.com/grpc/grpc-go/blob/master/examples/helloworld/helloworld/helloworld.proto))
98+
99+
### Behind the Scenes (Technical Working)
100+
101+
![Architecture](assets/architecture.png)
102+
103+
1. The gRPC service gets started in Dapr. We tell Dapr which port this gRPC server is running on through `--app-port` and give it a unique Dapr app ID with `--app-id <APP_ID_HERE>`
104+
2. We can now call the Dapr Sidecar through a client that will connect to the Sidecar
105+
3. Whilst calling the Dapr Sidecar, we provide a metadata key named `dapr-app-id` with the value of our gRPC server booted in Dapr (e.g. `server` in our example)
106+
4. Dapr will now forward the call to the gRPC server configured
107+
80108
## Building blocks
81109

82110
The JavaScript Client SDK allows you to interface with all of the [Dapr building blocks]({{< ref building-blocks >}}) focusing on Client to Sidecar features.

examples/grpc/proxying/README.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
We support gRPC proxying as shown in [community call 41](https://www.youtube.com/watch?v=B_vkXqptpXY&t=71s).
2+
3+
## How the JS SDK Supports this
4+
5+
6+
## Behind the Scenes (Technical Working)
7+
8+
![](assets/architecture.png)
9+
10+
1. The gRPC service gets started in Dapr. We tell Dapr which port this gRPC server is running on through `--app-port` and give it a unique Dapr APP Id with `--app-id <APP_ID_HERE>`
11+
2. We can now call the Dapr Sidecar through a client that will connect to the Sidecar
12+
3. Whilst calling the Dapr Sidecar, we provide a metadata key named `dapr-app-id` with the value of our gRPC server booted in Dapr (e.g. `server` in our example)
13+
4. Dapr will now forward the call to the gRPC server configured
14+
15+
## Example
16+
17+
The example provided is based on the Hello World example, where we have a server and a client. The server will just reply what the client sends.
18+
19+
```bash
20+
client/ # The client calling the gRPC server (through the Dapr JS SDK)
21+
server/ # The gRPC server
22+
helloworld/ # Contains our Proto description
23+
```
24+
25+
We will be using this proto file:
26+
https://github.com/grpc/grpc-go/blob/master/examples/helloworld/helloworld/helloworld.proto
27+
28+
### Start Server
29+
30+
```bash
31+
cd server/
32+
./start.sh
33+
```
34+
35+
### Start Client
36+
37+
```bash
38+
cd client/
39+
./start.sh
40+
```
41+
71.8 KB
Loading
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
#!/bin/bash
2+
OS=$(echo `uname`|tr '[:upper:]' '[:lower:]')
3+
ARCH=$(uname -m)
4+
5+
# Path to store output
6+
PATH_ROOT=$(pwd)
7+
8+
echo $PATH_ROOT
9+
10+
# Http request CLI
11+
HTTP_REQUEST_CLI=curl
12+
13+
# Make sure curl or wget are installed
14+
prerequisiteCheckHttpRequestCLI() {
15+
if type "curl" > /dev/null; then
16+
HTTP_REQUEST_CLI=curl
17+
elif type "wget" > /dev/null; then
18+
HTTP_REQUEST_CLI=wget
19+
else
20+
echo "Either curl or wget is required"
21+
exit 1
22+
fi
23+
}
24+
25+
prerequisiteCheckProtobuf() {
26+
if ! type "protoc" > /dev/null; then
27+
echo "protoc is not installed, trying to install"
28+
sudo apt update
29+
sudo apt install -y protobuf-compiler
30+
protoc --version
31+
32+
prerequisiteCheckProtobuf
33+
else
34+
echo "protoc ($(protoc --version)) installed"
35+
fi
36+
}
37+
38+
downloadFile() {
39+
SRC=$1
40+
DST=$2
41+
42+
# Ensure target path exists
43+
mkdir -p $(dirname $DST)
44+
45+
# Download the file
46+
echo "[$HTTP_REQUEST_CLI] Downloading $1 ..."
47+
if [ "$HTTP_REQUEST_CLI" == "curl" ]; then
48+
curl -SsL "$SRC" -o "$DST"
49+
else
50+
wget -q -P "$SRC" "$DST"
51+
fi
52+
echo "[$HTTP_REQUEST_CLI] Saved to $DST"
53+
}
54+
55+
generateGrpc() {
56+
PATH_PROTO=$1
57+
PATH_FILE=$2
58+
59+
echo "[protoc] Generating RPC for $PATH_PROTO/$PATH_FILE"
60+
61+
npx grpc_tools_node_protoc \
62+
--proto_path="${PATH_PROTO}" \
63+
--js_out="import_style=commonjs,binary:$PATH_PROTO" \
64+
--ts_out="grpc_js:$PATH_PROTO" \
65+
--grpc_out=grpc_js:$PATH_PROTO \
66+
"$PATH_PROTO/$PATH_FILE"
67+
}
68+
69+
fail_trap() {
70+
result=$?
71+
if [ $result != 0 ]; then
72+
echo "Failed to generate gRPC interface and proto buf: $ret_val"
73+
fi
74+
cleanup
75+
exit $result
76+
}
77+
78+
cleanup() {
79+
find $PATH_PROTO -type f -name '*.proto' -delete
80+
rm -rf protoc
81+
rm -f protoc.zip
82+
}
83+
84+
generateGrpcSuccess() {
85+
echo -e "\ngRPC interface and proto buf generated successfully!"
86+
}
87+
88+
# -----------------------------------------------------------------------------
89+
# main
90+
# -----------------------------------------------------------------------------
91+
#trap "fail_trap" EXIT
92+
93+
echo "Checking Dependencies"
94+
prerequisiteCheckProtobuf
95+
prerequisiteCheckHttpRequestCLI
96+
97+
echo ""
98+
echo "Removing old Proto Files"
99+
rm -rf "$PATH_ROOT/src/proto"
100+
mkdir -p "$PATH_ROOT/src/proto"
101+
102+
echo ""
103+
echo "Downloading latest gRPC files"
104+
downloadFile "https://raw.githubusercontent.com/grpc/grpc-go/master/examples/helloworld/helloworld/helloworld.proto" "$PATH_ROOT/src/proto/helloworld/helloworld.proto"
105+
106+
echo ""
107+
echo "Compiling gRPC files"
108+
generateGrpc "$PATH_ROOT/src/proto" "helloworld/helloworld.proto"
109+
110+
echo ""
111+
echo "DONE"
112+
113+
#cleanup
114+
115+
generateGrpcSuccess

0 commit comments

Comments
 (0)