Language-agnostic microservices boilerplate as a code
Project description
Language-agnostic microservices boilerplate as a code. You define service configuration and implementation, Harness takes care for it’s life cycle:
load configuration: read, validate
initialize environment: database and other outgoing connections
start servers/subscribers
graceful shutdown
Configuration
Harness uses Protocol Buffers as a configuration definition language (svc.proto file):
syntax = "proto3";
package cafe;
import "harness/options.proto";
import "harness/postgres.proto";
import "harness/grpc.proto";
message Configuration {
bool debug = 1;
harness.postgres.DSN db = 2 [(harness.options).input = "python/asyncpg.v1:Connection"];
harness.grpc.Channel taskqueue = 3 [(harness.options).input = "python/grpclib.v1:Channel"];
harness.grpc.Endpoint listen = 4 [(harness.options).output = "python/grpclib.v1:Server"];
}
As you can see from this configuration, our service has:
debug mode
database connection
gRPC channel to the taskqueue service
gRPC server to serve incoming requests
We can provide values for this configuration using YAML file (config.yaml file):
db:
value: postgres://postgres:postgres@db.cafe.svc.cluster.local:5432/coffee
taskqueue:
host: taskqueue.platform.svc.cluster.local
port: 50051
listen:
host: 0.0.0.0
port: 50051
Service Definition
Harness must be able to run your service. In order to do this you must provide a main function, it’s signature looks like this:
from svc_wires import WiresIn, WiresOut
async def main(wires_in: WiresIn) -> WiresOut:
...
return WiresOut(...)
Where WiresIn and WiresOut are generated by the Harness from your service configuration:
@dataclass
class WiresIn:
db: harness.resources.asyncpg.v1.Connection
taskqueue: harness.resources.grpclib.v1.Channel
@dataclass
class WiresOut:
listen: harness.resources.grpclib.v1.Server
When Harness runs your service, you receive already initialized environment in a WiresIn structure. All you have to do is to setup your request handler and return it with a WiresOut structure (svc.py file):
from harness.resources.grpclib.v1 import Server
from svc_grpc import CoffeeMachineBase
class CoffeeMachine(CoffeeMachineBase):
...
async def main(wires_in: WiresIn) -> WiresOut:
print('Connection:', wires_in.db.connection)
print('Channel:', wires_in.taskqueue.channel)
server_resource = Server([
CoffeeMachine(
db=wires_in.db.connection,
taskqueue=wires_in.taskqueue.channel,
),
])
return WiresOut(listen=server_resource)
Files Generation
We use protoc compiler to generate boilerplate from your configuration:
$ protoc -I $HARNESS_PROTO --python_out=. --python_grpc_out=. --python_harness_out=. --mypy_out=. svc.proto
Where $HARNESS_PROTO is where to find Harness proto-files.
Runtime
Use harness command to run your service:
$ harness svc:main config.yaml
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.