> ## Documentation Index
> Fetch the complete documentation index at: https://docs.restate.dev/llms.txt
> Use this file to discover all available pages before exploring further.

<AgentInstructions>

## Submitting Feedback

If you encounter incorrect, outdated, or confusing documentation on this page, submit feedback:

POST https://docs.restate.dev/feedback

```json
{
  "path": "/develop/go/code-generation",
  "feedback": "Description of the issue"
}
```

Only submit feedback when you have something specific and actionable to report.

</AgentInstructions>

# Code Generation

> Use proto for type-safe servers and clients.

The Go SDK supports generating typed clients and server interfaces from
[Protocol Buffer service definitions](https://protobuf.dev/programming-guides/proto3/#services).
A full example can be found in the [SDK repository](https://github.com/restatedev/sdk-go/tree/main/examples/codegen).

Code generation relies on the tool `protoc-gen-go-restate` which you can install using
`go install github.com/restatedev/sdk-go/protoc-gen-go-restate@latest`, in addition to `protoc`
which you can install from the [Protobuf compiler repo](https://github.com/protocolbuffers/protobuf#protobuf-compiler-installation).

## Defining a service

To get started, create a Protocol Buffer definition file defining a service:

```proto service.proto {"CODE_LOAD::go/develop/codegen/proto/service.proto#service"}  theme={null}
package greeter;

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloResponse) {}
}

message HelloRequest {
  string name = 1;
}

message HelloResponse {
  string message = 1;
}
```

You can compile this file into Go types and your Restate generated code with:

```shell theme={null}
protoc --go_out=. --go_opt=paths=source_relative --go-restate_out=. --go-restate_opt=paths=source_relative proto/service.proto
```

This creates two files: `service.pb.go` containing Go types, and `service_restate.pb.go` which contains several useful objects:

1. `NewGreeterClient`, which returns an interface for making type-safe calls to the Greeter service. The default serialization
   for request and response data is the [canonical Protobuf JSON encoding](https://protobuf.dev/programming-guides/proto3/#json),
   but this is configurable.
2. `GreeterServer`, an interface for server code to implement. An implementor can be converted into a service definition with
   `NewGreeterServer`.
3. `UnimplementedGreeterServer`, an empty struct that implements `GreeterServer` by just returning 'not implemented' terminal
   errors for each method. You can choose to embed this struct into your own implementation struct, in which case new methods
   in the Protobuf definition will not cause compilation errors in your Go code, which can help with backwards compatibility.

<Info>
  Both `NewGreeterClient` and `NewGreeterServer` accept option parameters which can be used to set a different serialization codec.
  For example, you can use Protobuf by providing `restate.WithProto` to both functions.
</Info>

## Implementing the server

Next, you can implement the `GreeterServer` interface and bind it to your Restate server.

```go {"CODE_LOAD::go/develop/codegen/codegen.go#server"}  theme={null}
type greeter struct {
  proto.UnimplementedGreeterServer
}

func (greeter) SayHello(ctx restate.Context, req *proto.HelloRequest) (*proto.HelloResponse, error) {
  return &proto.HelloResponse{
    Message: fmt.Sprintf("%s!", req.Name),
  }, nil
}

func main() {
  if err := server.NewRestate().
    Bind(proto.NewGreeterServer(greeter{})).
    Start(context.Background(), ":9080"); err != nil {
    log.Fatal(err)
  }
}
```

## Using the client

`NewGreeterClient` will return a similar client to what you'd get from `restate.Service`, with additional
type safety for method names and request/response types.

```go {"CODE_LOAD::go/develop/codegen/codegen.go#client"}  theme={null}
client := proto.NewGreeterClient(ctx)
resp, err := client.SayHello().Request(&proto.HelloRequest{Name: "world"})
if err != nil {
  return err
}
```

## Defining Virtual Objects and Workflows

To define a Virtual Object or Workflow, you will need to provide the option `dev.restate.sdk.go.service_type` when defining the service.
This option is defined by the Go SDK's proto file
[`dev/restate/sdk/go.proto`](https://github.com/restatedev/sdk-go/blob/main/proto/dev/restate/sdk/go.proto) which must be imported in your own file,
and a directory containing it must be provided to protoc eg with `-I $GOPATH/src/github.com/restatedev/sdk-go/proto`

You may additionally provide the option `dev.restate.sdk.go.handler_type` to denote that the handler is a shared handler.

```proto service.proto {"CODE_LOAD::go/develop/codegen/proto/service.proto#virtual_object"}  theme={null}
import "dev/restate/sdk/go.proto";

service Counter {
  option (dev.restate.sdk.go.service_type) = VIRTUAL_OBJECT;
  rpc Add (AddRequest) returns (AddResponse) {}
  rpc Get (GetRequest) returns (GetResponse) {
    option (dev.restate.sdk.go.handler_type) = SHARED;
  }
}

service Workflow {
  option (dev.restate.sdk.go.service_type) = WORKFLOW;
  rpc Run (RunRequest) returns (RunResponse) {}
  rpc GetStatus (GetStatusRequest) returns (GetStatusResponse) {}
}
```

Clients are instantiated with a key:

```go {"CODE_LOAD::go/develop/codegen/codegen.go#virtual_object_client"}  theme={null}
client := proto.NewCounterClient(ctx, "key-1")
resp, err := client.Add().Request(&proto.AddRequest{Delta: 1})
if err != nil {
  return err
}
```

<Accordion title="Easier Protobuf with Buf">
  Instead of manually wrangling `protoc` to handle generation and proto imports,
  it can be a lot easier to use [Buf](https://buf.build/).

  Buf determines what code to generate based on a `buf.gen.yaml` file:

  ```yaml theme={null}
  version: v2
  managed:
    enabled: true
  plugins:
    - remote: buf.build/protocolbuffers/go:v1.34.2
      out: .
      opt: paths=source_relative
    - local: protoc-gen-go-restate
      out: .
      opt: paths=source_relative
  inputs:
    - directory: .
  ```

  And to allow the import of `dev/restate/sdk/go.proto`, you can specify the dependency in your `buf.yaml`:

  ```yaml theme={null}
  version: v2
  lint:
    use:
      - DEFAULT
  breaking:
    use:
      - FILE
  deps:
    - buf.build/restatedev/sdk-go
  ```

  Then you can run `buf generate` to generate the code.
</Accordion>
