Skip to content

Latest commit

 

History

History
210 lines (156 loc) · 8.68 KB

README.md

File metadata and controls

210 lines (156 loc) · 8.68 KB

readysetgo

Starter template for a monorepo for Go microservices using gRPC, Bazel, and Tilt

License Last Commit

Build System Service Transport Go Version

Build Test Buf Lint Tilt Buildifier

Prerequisites

Nix (recommended)

If you want to use Nix, all you need to do is install Nix. Then, just run nix-shell from the repository root to get a fully-configured shell.

However, some of your tools (e.g. IDE) might behave better if you also install things locally using the directions below.

Homebrew (also recommended)

If you're using macOS or Linux, you can install all required tools easily using the Homebrew bundle defined in Brewfile:

brew bundle install

Windows

Even if you're using Windows, you should probably use the Windows Subsystem for Linux wherever possible.

Some of the tools can also be installed on your Windows instance to allow IDE integration. The easiest way to do this is to use Chocolatey:

choco install go bazelisk buildifier protoc

Manual

If for any reason you need to install them manually, this table contains all of the required tools:

Tool Install instructions
Bazelisk instructions
Buf instructions
Tilt instructions
Kubernetes CLI (kubectl) instructions
Docker instructions
minikube instructions
grpc_cli instructions
buildifier instructions

Initializing Your Repository

Run the tidy.sh script to initialize your repository after cloning and installing prerequisites:

bazel run //:tidy

You should also run this script after doing any of the following:

  • Modifying protobuf files
  • Adding/remove dependencies to Go code

Running the Environment with Tilt

If you haven't already, start up a Kubernetes cluster:

minikube start

Then, run Tilt and follow the instructions in the terminal to open the web console:

tilt up

Running Servers Individually

gRPC Server

bazel run //src/example/service:server

HTTP Server

bazel run //src/example/web/server

Testing the gRPC Server

grpc_cli is an easy way to issue requests to the gRPC server:

grpc_cli call localhost:50051 ExampleService/GetExample "id: 'foo'"
grpc_cli call localhost:50051 ExampleService/SetExample "id: 'foo', data: {text: 'bar'}"
grpc_cli call localhost:50051 ExampleService/GetExample "id: 'foo'"

To-do List for this Repository

Near Term Tasks

  • Add code quality scan to CI
  • Add code coverage to CI
  • Add Gazelle to CI
  • Add PR comments for CI errors wherever possible
  • Add git hooks and repository setup script
  • Generify HTTP server
  • Add documentation for CI
  • Add database to environment
  • Add ORM to any example server

Potential Future Projects

  • Add service resource dependencies to Tilt environment
  • Add project configuration/generator/wizard so people don't get features they don't want
  • Add TypeScript React app to example HTTP server
  • Add support for other backend languages
  • Add Deno scripts to simplify custom workflows
  • Add production deployment examples
  • Add dynamic configs to environment
  • Add pubsub to any example server
  • Add cache to any example server
  • Add authentication to generic server
  • Add authorization to generic server
  • Add auditing to generic server
  • Add monitoring to generic server
  • Add distributed tracing to generic server
  • Add single-server integration tests
  • Add multi-server API simulation tests
  • Add multi-server end-to-end tests
  • Add new service setup wizard

Philosophy

The goal of this template is to provide something that you can use to instantly create a production-worthy enterprise microservice environment. The environment aims to be opinionated about:

  • Core dependencies (e.g. Bazel, Protocol Buffers)
  • Practices
  • Abstractions (e.g. good API definitions, service isolation/composition).

However, these pieces should be able to plug into any particular technologies (e.g. PostgreSQL, Okta, Kong) desired, and this template should remain strictly neutral on those opinions. Providing plugins/helpers to make certain integrations easier does not mean assuming that technology will be used.

The assumptions we make about the target environment are:

  • It will use Bazel for builds (could support others in the future)
  • It will contain services written in Go (could support others in the future)
  • It will use Protocol Buffers for service descriptors (could support others in the future)
  • It will use gRPC and/or HTTP for transport
  • It will run in Kubernetes
  • It will use Tilt to manage local development environments

Shared Plugins vs Template Plugins

Currently, most of the custom work in this environment is contained within this repo. That means that you won't get any future updates made, but it also means you can customize things to your heart's desire.

The eventual goal is to strike a good balance on this, allowing both models easily. It's quite possible that those shared mechanisms will be removed from this repository and used as shared resources in the future, similarly to how we use existing tools like Gazelle.

Servers != Services

There are two fundamentally different things that people might mean when they say these words, so it's important to be clear. When this environment discusses these terms, they have these definitions:

  • Service: An API with defined methods that take certain inputs and produce outputs
  • Server: A long-running application that provides service(s) over a network interface

These should be decoupled as much as possible. The size of your thread pool (server) may be related to the kind of data processing in your business logic (service), but they are still separate concerns that are often managed by separate people.