
# Go

Start with the [gRPC guide](../grpc.md) to get a Platform API token and download `platform.proto`. Install `protoc`, Go, and the [Go protobuf plugins](https://grpc.io/docs/languages/go/quickstart/).

Create a module and install the generators:

```bash
go mod init example.com/reconstruct-client
```

```bash
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
```

```bash
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
```

Make the plugins available to `protoc`, then generate the client. Replace `example.com/reconstruct-client` in both the module and command if you use another module path:

```bash
export PATH="$(go env GOPATH)/bin:$PATH"
mkdir -p platformpb
protoc -I. platform.proto \
  --go_out=platformpb --go_opt=paths=source_relative \
  --go_opt=Mplatform.proto=example.com/reconstruct-client/platformpb \
  --go-grpc_out=platformpb --go-grpc_opt=paths=source_relative \
  --go-grpc_opt=Mplatform.proto=example.com/reconstruct-client/platformpb
```

Save as `main.go` next to `platform.proto`:

```go
package main

import (
    "context"
    "fmt"
    "log"
    "os"
    "time"

    pb "example.com/reconstruct-client/platformpb"
    "google.golang.org/grpc"
    "google.golang.org/grpc/credentials"
    "google.golang.org/grpc/metadata"
)

func main() {
    token := os.Getenv("CR_RECONSTRUCT_API_TOKEN")
    if token == "" { log.Fatal("set CR_RECONSTRUCT_API_TOKEN") }

    conn, err := grpc.NewClient("reconstruct.dev:443",
        grpc.WithTransportCredentials(credentials.NewClientTLSFromCert(nil, "")))
    if err != nil { log.Fatal(err) }
    defer conn.Close()

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()
    ctx = metadata.AppendToOutgoingContext(ctx, "authorization", "Bearer "+token)
    client := pb.NewPlatformServiceClient(conn)

    page, err := client.ListCatalogs(ctx, &pb.ListCatalogsRequest{PageSize: 10})
    if err != nil { log.Fatal(err) }
    for _, catalog := range page.GetCatalogs() {
        detail, err := client.GetCatalog(ctx, &pb.GetCatalogRequest{CatalogId: catalog.GetCatalogId()})
        if err != nil { log.Fatal(err) }
        fmt.Println(detail.GetCatalogId(), detail.GetDescription())
    }
}
```

Run `go mod tidy`, then `go run .`. The generated files are `platformpb/platform.pb.go` and `platformpb/platform_grpc.pb.go`.
