Skip to content

Getting started

This tutorial dials a gRPC server through the factory, then adds TLS and a transit client interceptor — enough to see what Dial gives you and how the go/transit middleware layers on.

Install

go get gitlab.com/phpboyscout/go/grpcclient

Dial a local server

Dial returns an ordinary *grpc.ClientConn — you use it exactly as you would one from grpc.NewClient. With TLS disabled it uses insecure loopback credentials, the common case for a co-located local server:

package main

import (
    "gitlab.com/phpboyscout/go/grpcclient"
)

func main() {
    conn, err := grpcclient.Dial(grpcclient.Target{Port: 8080})
    if err != nil {
        panic(err)
    }
    defer conn.Close()

    // client := pb.NewYourServiceClient(conn)
    // client.DoThing(ctx, &pb.Request{})
}

An empty Host resolves to loopback (localhost). The connection is lazy — like grpc.NewClient, no network I/O happens until the first RPC.

Trust a private CA

For a server presenting a certificate from a private authority, enable TLS on the target and point Cert at the CA bundle. The hardened go/tls client config (TLS 1.2 floor, curated cipher suites) is used automatically:

import gtls "gitlab.com/phpboyscout/go/tls"

conn, err := grpcclient.Dial(grpcclient.Target{
    Host: "svc.internal",
    Port: 443,
    TLS:  gtls.Pair{Enabled: true, Cert: "/etc/pki/internal-ca.pem"},
})

With Enabled: true and an empty Cert, the client trusts the system roots.

Add a transit interceptor

The client interceptors — circuit breaking, OpenTelemetry, logging — live in go/transit and are passed to Dial as ordinary grpc.DialOptions:

import (
    transitgrpc "gitlab.com/phpboyscout/go/transit/grpc"
    "google.golang.org/grpc"
)

conn, err := grpcclient.Dial(
    grpcclient.Target{Port: 8080},
    grpc.WithChainUnaryInterceptor(
        transitgrpc.CircuitBreakerInterceptor(log, transitgrpc.DefaultCircuitBreakerConfig()),
    ),
    transitgrpc.OTelClientHandler(),
)

Where next