examples/addsvc: README and other documentation
Peter Bourgon
6 years ago
|
0 |
# addsvc
|
|
1 |
|
|
2 |
addsvc is an example microservice which takes full advantage of most of Go
|
|
3 |
kit's features, including both service- and transport-level middlewares,
|
|
4 |
speaking multiple transports simultaneously, distributed tracing, and rich
|
|
5 |
error definitions. The server binary is available in cmd/addsvc. The client
|
|
6 |
binary is available in cmd/addcli.
|
|
7 |
|
|
8 |
Finally, the addtransport package provides both server and clients for each
|
|
9 |
supported transport. The client structs bake-in certain middlewares, in order to
|
|
10 |
demonstrate the _client library pattern_. But beware: client libraries are
|
|
11 |
generally a bad idea, because they easily lead to the
|
|
12 |
[distributed monolith antipattern](https://www.microservices.com/talks/dont-build-a-distributed-monolith/).
|
|
13 |
If you don't _know_ you need to use one in your organization, it's probably best
|
|
14 |
avoided: prefer moving that logic to consumers, and relying on
|
|
15 |
[contract testing](https://docs.pact.io/best_practices/contract_tests_not_functional_tests.html)
|
|
16 |
to detect incompatibilities.
|
67 | 67 |
|
68 | 68 |
// NewGRPCClient returns an AddService backed by a gRPC server at the other end
|
69 | 69 |
// of the conn. The caller is responsible for constructing the conn, and
|
70 | |
// eventually closing the underlying transport.
|
|
70 |
// eventually closing the underlying transport. We bake-in certain middlewares,
|
|
71 |
// implementing the client library pattern.
|
71 | 72 |
func NewGRPCClient(conn *grpc.ClientConn, tracer stdopentracing.Tracer, logger log.Logger) addservice.Service {
|
72 | 73 |
// We construct a single ratelimiter middleware, to limit the total outgoing
|
73 | 74 |
// QPS from this client to all methods on the remote instance. We also
|
50 | 50 |
|
51 | 51 |
// NewHTTPClient returns an AddService backed by an HTTP server living at the
|
52 | 52 |
// remote instance. We expect instance to come from a service discovery system,
|
53 | |
// so likely of the form "host:port".
|
|
53 |
// so likely of the form "host:port". We bake-in certain middlewares,
|
|
54 |
// implementing the client library pattern.
|
54 | 55 |
func NewHTTPClient(instance string, tracer stdopentracing.Tracer, logger log.Logger) (addservice.Service, error) {
|
55 | 56 |
// Quickly sanitize the instance string.
|
56 | 57 |
if !strings.HasPrefix(instance, "http") {
|
50 | 50 |
|
51 | 51 |
// NewThriftClient returns an AddService backed by a Thrift server described by
|
52 | 52 |
// the provided client. The caller is responsible for constructing the client,
|
53 | |
// and eventually closing the underlying transport.
|
|
53 |
// and eventually closing the underlying transport. We bake-in certain middlewares,
|
|
54 |
// implementing the client library pattern.
|
54 | 55 |
func NewThriftClient(client *addthrift.AddServiceClient) addservice.Service {
|
55 | 56 |
// We construct a single ratelimiter middleware, to limit the total outgoing
|
56 | 57 |
// QPS from this client to all methods on the remote instance. We also
|