Flutter ❤ GRPC

Using flutter with a GRPC backend and living the HTTP/2 life!

Preface

A few months ago, I decided to write an app for finding people around you with similar interests with the help of events. Having experience only in Android development, I couldn’t attempt to do purely native development for both Android and iOS, so I decided to go with something that targets both and requires the least amount of platform specific code. Choices:

  1. React Native (Sort of an industry standard right now)
  2. Flutter (In beta at the time, now RC2)

I had used react-native for a couple of projects before, and I really loved RN for that, but there were so many issues with RN, and the whole trying to use native components by wrapping them and calling them over a JS bridge. That does bring a lot of inconsistencies with the native platform and react native’s wrapper. So, I decided to pick up Flutter.

With flutter, things were a bit different:

  1. First I needed to learn dart, which seemingly isn’t all that bad, and quite easy to pick up. It has a syntax most people are familiar with (ES derived maybe?) and has a bunch on syntactic sugar on top of it, like arrow functions, argument only constructors that don’t require manual wiring etc.
  2. The structure of flutter apps is something that takes time getting used to, and believe me, I am still not used to it. With android you see things organised into views, controller and models, but with flutter everything is a widget, quite literally, which makes things complex quite easily if you don’t force yourself to cut components out to their separate widgets and create services etc. So it takes a bit of time getting used to.
  3. And then there is plugins, flutter mostly acts like a view framework of sorts and does lack a lot of basic functionality right now, like geolocation, local-notifications, handling of deep links and everything is handled by either third party plugins or some firebase plugins for now. Even maps lacks a first party plugin, its coming soon, follow this issue if you’re looking for that https://github.com/flutter/flutter/issues/19030

But with flutter, more precisely dart, there was complete support for GRPC, which JS lacked at that time, now there is grpc-web by the same team that built GRPC.

Anyway, let’s get to the main point of discussion, using GRPC with Flutter. When I decided I want to build a flutter app, I was also playing around with GRPC as a backend choice in GoLang. But the internet lacked any such documentation or blogposts of people attempting it. So I though I should do a small tutorial on making a simple app with a GRPC backend. I think I will be covering some more advanced topics like token (JWT) based auth, streams, TLS based authentication from apps etc in upcoming posts, but in this one, let’s build a simple hello world style app that talks to a GRPC server.


Protocol buffers

To get started with creating your first flutter project, follow the guide here https://flutter.io/get-started/install/

Flutter code-labs and docs are the best resources to learn about flutter, so pay them a visit if you’re stuck somewhere.

Let’s first write the proto definitions and a simple Go backend.

The directory structure is somewhat like this:

hello-grpc/
- model/
- gen/
- ship/
- dart/
- hello.pb.go
- protodefs/
- hello.proto
- gen/
- makefile
- main.go

The proto file, hello.proto

hello.proto defines a simple RPC call

So let’s generate the Go and dart proto stubs.

Note: For GoLang, its pretty straight forward, but for dart, if you use Google’s own proto implementations like I used google.protobuf.Empty, then you also need to ship all Google’s implementation stubs along with your own. Related issue: https://github.com/grpc/grpc-dart/issues/76

To generate the proto files, I use a simple makefile, to make things easier and forget the actual commands ;)

Makefile used to build the dart and Golang GRPC stubs

Now simply generate the code using

make gen

That will create go and dart stubs in `model/gen` and `model/gen/ship/dart` respectively.

Check out the simple go server here


Flutter

Moving on to the flutter side of things. Assuming you have it all setup, let’s go ahead and plug GRPC code into it.

GRPC clients are smart, that means you generally don’t need to either manage connections or pooling for the clients. It automatically decides how many parallel steams/connections it needs over HTTP/2 and one doesn’t need to worry about that. It can even do client side load balancing using look-aside LB or a service discovery, check https://grpc.io/blog/loadbalancing

To create a client implementation, copy the generated proto stubs for dart to your main project, I try to keep my code structure as follows:

helloworld/
- android/
- ios/
- lib/
- assets/
- common/
- grpc_commons.dart # holds the singleton
- model/
- google/
- hello.pb.dart
- hello.pbenum.dart
- hello.pbgrpc.dart
- hello.pbjson.dart
- services/
- hello_service.dart
- views/
- hello_world.dart
- main.dart
- pubspac.yaml

I’ll try to explain which file holds what and then we can see the code for them. There are 4 important things here:

  1. gprc_commons.dart Holds the code for a singleton object to the GRPC client, and the client itself takes care of reconnection, pooling and everything else. For now, to keep it simple, we have just used the client connection in non secure mode and no authentication.
  2. hello_service.dart I try to do some sort of separation of concern in dart code, I hate everything in one file, so all the network calls go in a services folder, and this service basically calls the RPC SayHello .
  3. main.dart & views , main.dart should just be the entry point to the app, and then further views or routes should be separately managed. To save some time in this codebase I’ve written everything in main.dart, but as the project grows, it’s always better to just break it into separate view, components (re-usable) and routing logics.
  4. pubspec.yaml is the main file for dependency management in flutter, and honestly is super smooth when coming from the super complicated dependency hell “Gradle”. This is where you will add dependencies for protobuf and grpc .

Let’s see some code samples, incoming Github gist!

If you’ve managed to get this far, and have a grpc server up and running, let’s see what the amazing hello app looks like

Server says hi!

So, if the above worked for you, I guess it should be a great starting point for you to begin some hacking around with GRPC and flutter.

I will be posting about other topics ranging from GRPC TLS connection to servers from flutter apps, deploying your backend apps behind K8s and using that as a service discovery for GRPC client side load balancing. I’ve had to figure these things out in a pretty hard fashion, so I’d love to share whatever knowledge I’ve gained over the past few months.

Flutter documentation is great but sometimes it can be a pain to understand a particular widget which has no examples at all, or is just super hard to understand, and since StackOverflow is still not quite there yet for Flutter, its always better to visit flutter and search your particular issue, just remember to remove the is:open filter from search.


This has been a long post, and my first actual blog entry at Medium. Will try to keep the next ones and concise.

You can find the flutter codebase here

As I mentioned, I’ve been working with Flutter & GRPC for a product that we’re now beta testing with public participants. If you’re interested in trying it out, please visit the PlayStore at: