# Source: https://raw.githubusercontent.com/ServiceStack/docs.servicestack.net/refs/heads/main/MyApp/_pages/grpc/go.md

---
slug: grpc-go
title: gRPC protoc GO Client
---

[![](/img/pages/grpc/go.png)](https://youtu.be/FYA32J1-IA0)

::: info YouTube
[youtu.be/FYA32J1-IA0](https://youtu.be/FYA32J1-IA0)
:::

## Go protoc generated GrpcServiceClient TodoWorld Example

Install [x dotnet tool](/dotnet-tool):
    
```bash
$ dotnet tool install --global x 
```

Create new **TodoWorld** Go module:

```bash
$ go mod init TodoWorld
```

Add protoc generated TodoWorld DTOs and gRPC GrpcServiceClient to `services/` folder:

```bash
$ mkdir services
$ x proto-go https://todoworld.servicestack.net -out services
```

### Go protoc gRPC insecure Example

Create a new Go Console App in `client\main.go`:

```go
package main

import (
    context "context"
    "fmt"
    "log"

    "google.golang.org/grpc"

    pb "TodoWorld/services"
    "time"
)

func main() {
    conn, err := grpc.Dial("todoworld.servicestack.net:5054", grpc.WithInsecure())
    if err != nil {
        log.Fatalf("fail to dial: %v", err)
    }
    defer conn.Close()

    client := pb.NewGrpcServicesClient(conn)
    ctx, cancel := context.WithTimeout(context.Background(), time.Second)
    defer cancel()

    response, err := client.GetHello(ctx, &pb.Hello{Name: "gRPC Go"})
    if err != nil {
        log.Fatalf("GetHello: %v", err)
    }
    fmt.Println(response.Result)
}
```

Alternatively above Go example can be created with:

```bash
$ mkdir client
$ npx add-in todoworld-go -out client
```

Run example:

```bash
$ go run client\main.go
```

### Go protoc gRPC SSL Example

Download TodoWorld SSL Certificate used for its gRPC HTTP/2 Services:

```bash
$ x get https://todoworld.servicestack.net/grpc.crt 
```

Use certificate when initializing `NewGrpcServicesClient`:

```go
package main

import (
    context "context"
    "fmt"
    "log"

    "google.golang.org/grpc"
    "google.golang.org/grpc/credentials"

    pb "TodoWorld/services"
    "time"
)

func main() {
    creds, err := credentials.NewClientTLSFromFile("grpc.crt", "")
    if err != nil {
        log.Fatalf("could not process the credentials: %v", err)
    }

    conn, err := grpc.Dial("todoworld.servicestack.net:50051", grpc.WithTransportCredentials(creds))
    if err != nil {
        log.Fatalf("fail to dial: %v", err)
    }
    defer conn.Close()

    client := pb.NewGrpcServicesClient(conn)
    ctx, cancel := context.WithTimeout(context.Background(), time.Second)
    defer cancel()

    response, err := client.GetHello(ctx, &pb.Hello{Name: "gRPC Go"})
    if err != nil {
        log.Fatalf("GetHello: %v", err)
    }
    fmt.Println(response.Result)
}
```

Override `client/main.go` with the above Go Example: 

```bash
$ npx add-in todoworld-go-ssl -out client
```

Run example:

```bash
$ go run client\main.go
```

### Go Local Development gRPC SSL CRUD Example

```go
package main

import (
    context "context"
    "fmt"
    "log"

    "google.golang.org/grpc"
    "google.golang.org/grpc/credentials"

    "time"
    pb "todoworld/services"
)

func main() {

    // Load the certificates from disk
    creds, err := credentials.NewClientTLSFromFile("dev.crt", "localhost:5001")
    if err != nil {
        log.Fatalf("could not process the credentials: %v", err)
    }

    conn, err := grpc.Dial(address, grpc.WithTransportCredentials(creds))
    if err != nil {
        log.Fatalf("fail to dial: %v", err)
    }
    defer conn.Close()

    client := pb.NewGrpcServicesClient(conn)
    ctx, cancel := context.WithTimeout(context.Background(), time.Second)
    defer cancel()


    _, err = client.PostResetTodos(ctx, &pb.ResetTodos{})
    if err != nil {
        log.Fatalf("PostResetTodos: %v", err)
    }

    fmt.Println("TODO EXAMPLE")

    //POST /todos
    r1, err := client.PostCreateTodo(ctx, &pb.CreateTodo{Title: "ServiceStack"})
    if err != nil {
        log.Fatalf("PostCreateTodo: %v", err)
    }
    todo := r1.Result
    fmt.Println("new todo Id:", todo.Id, "Title:", todo.Title)

    //GET /todos
    all, err := client.CallGetTodos(ctx, &pb.GetTodos{})
    if err != nil {
        log.Fatalf("CallGetTodos: %v", err)
    }
    fmt.Println("todos:", len(all.GetResults()))

    //GET /todos/1
    r2, err := client.CallGetTodo(ctx, &pb.GetTodo{Id: todo.Id})
    if err != nil {
        log.Fatalf("CallGetTodo: %v", err)
    }
    todo = r2.Result
    fmt.Println("get todo Id:", todo.Id, "Title:", todo.Title)

    //PUT /todos/1
    _, err = client.PutUpdateTodo(ctx, &pb.UpdateTodo{Id: todo.Id, Title: "gRPC"})
    if err != nil {
        log.Fatalf("PutUpdateTodo: %v", err)
    }

    //GET /todos/1
    r2, err = client.CallGetTodo(ctx, &pb.GetTodo{Id: todo.Id})
    if err != nil {
        log.Fatalf("CallGetTodo: %v", err)
    }
    todo = r2.Result
    fmt.Println("get todo Id:", todo.Id, "Title:", todo.Title)

    //DELETE /todos/1
    _, err = client.CallDeleteTodo(ctx, &pb.DeleteTodo{Id: todo.Id})
    if err != nil {
        log.Fatalf("CallDeleteTodo: %v", err)
    }

    //GET /todos
    all, err = client.CallGetTodos(ctx, &pb.GetTodos{})
    if err != nil {
        log.Fatalf("CallGetTodos: %v", err)
    }
    fmt.Println("todos:", len(all.GetResults()))
}
```

Refer to [/clients/go](https://github.com/NetCoreApps/todo-world/tree/master/clients/go)
for a complete example project.