First Steps in gRPC Bindings for React Native
When you want to use gRPC in your React Native app there is no official support yet, but that shouldn’t stop you! In this post I’ll show you how we designed an implementation with type safety in mind and successfully called a service remotely from React Native on Android.
At the previous Innovation Day of Xebia, I had the pleasure of teaming up on implementing a microservice architecture using gRPC. gRPC is a remote procedure call framework (as the name suggests) and focuses on both high performance as well as availability in the most common programming languages. It utilises protocol buffers, a binary format for communicating messages, which is normally passed over the HTTP2 stack.
My personal goal was to create an Android React Native binding for one of the ‘consuming’ client services in our architecture. One possible solution we looked into was to use the
After a short sketching session, we came to the conclusion that we could leverage the React Native bridge and use the generated Android Java RPC stub services without many painful memory translations. Furthermore we scoped the solution by only implementing a single request/response. Streaming responses will be a topic for another Innovation Day and post.
Our design of a single gRPC request from React Native to a gRPC endpoint looks like this:
Promise instance to respond asynchronously.
Then, the native method creates a RPC
Request object from the
ReadableMap data and performs the actual request using the generated service stub. This transforms the request payload into a protocol buffer byte array which is sent over to the server.
After the server responds to the request, the happy path response handling looks like this:
The generated service stub is provided with a callback method which transforms the server response into a
WritableMap object and resolves the Java
Promise with that object. This triggers a
A nice bonus is that we can
try .. catch such an exception.
We start simple by basing our application on one of the classic examples from gRPC: a hello world Android client and Java server. The shared RPC interface contract is defined in a
.proto file as follows:
Based on this definition, a
GreeterGrpc class can be generated for the Android client which handles the actual network interaction, together with
HellyReply classes which handle the (de)serialization of requests and responses.
In a freshly installed React Native project, we add the
com.google.protobuf plugin and dependencies to the app Gradle configuration and set it up just like the official Android example. On every recompile, the React Native project now gets freshly generated stubs and message classes.
ResponseTask (which is omitted for brevity) takes care of the gRPC channel and does the network call on a separate thread. If anything goes wrong on this thread, the
responsePromise is rejected with the thrown
Here’s what our implementation looks like:
React Native exposes all native modules via the
NativeModules module. Because the
sayHello native method accepts a Java
Promise argument, the
Promise. We just wrap this function with some extra type information and export it in a nested fashion.
To use it, we can import
await the result of
The Work in Progress
.proto file as input and can be run at build time together with the generation of the stubs. However, this tool is by far from finished and not production-ready, as supporting all features from gRPC is a little too much for a single day.
All in all it was an exciting Innovation Day and good to see that we have a working gRPC solution for React Native on Android in less than a day.
The example project code is available at GitHub.