# Use Connect for incoming gRPC requests


The [Connect protocol](https://connectrpc.com/) is an HTTP/2-based protocol for RPC communication.
It's conceptually similar to gRPC, but with better support for using from browsers and JavaScript clients.

This guide shows how to use Encore for setting up a Connect service for external clients to use:

1. First, we'll define a simple gRPC service using Protobuf and Connect.
2. Then, we'll implement the service in Go, using [connect-go](https://connectrpc.com/docs/go/getting-started).
3. Then, we'll mount the Connect service into Encore with a raw endpoint.
4. Finally, we'll call the Connect service from cURL using its JSON mapping.

## Define a Connect service

We'll largely follow the connect-go [getting started guide](https://connectrpc.com/docs/go/getting-started)
with some small tweaks.

Start by installing the necessary tools:

```shell
$ go install github.com/bufbuild/buf/cmd/buf@latest
$ go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest
$ go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
$ go install connectrpc.com/connect/cmd/protoc-gen-connect-go@latest
```

Next, inside your Encore application ([create one if you haven't already](/docs/go/quick-start))
create a new file at `greet/v1/greet.proto` with the following contents:

```
-- greet/v1/greet.proto --
syntax = "proto3";

package greet.v1;

option go_package = "encore.app/gen/greet/v1;greetv1";

message GreetRequest {
  string name = 1;
}

message GreetResponse {
  string greeting = 1;
}

service GreetService {
  rpc Greet(GreetRequest) returns (GreetResponse) {}
}
```

Next, add a `buf.gen.yaml` in the repository root, containing:

```
-- buf.gen.yaml --
version: v2
plugins:
  - local: protoc-gen-go
    out: gen
    opt: paths=source_relative
  - local: protoc-gen-connect-go
    out: gen
    opt: paths=source_relative
```

Now it's time to generate the connect-go service code. Run:

```shell
$ buf lint
$ buf generate
```

If all went well, you should see a new `gen` directory in the repository root containing some generated Go code:

```
gen
└── greet
    └── v1
        ├── greet.pb.go
        └── greetv1connect
            └── greet.connect.go
```

## Implement the service

Now that we have the service definition, we can implement the Connect service in Go.

Add the file `greet/greet.go` with the following contents:

```
-- greet/greet.go --
package greet

import (
	"context"
	"fmt"
	"log"

	"connectrpc.com/connect"

	greetv1 "encore.app/gen/greet/v1" // generated by protoc-gen-go
)

type GreetServer struct{}

func (s *GreetServer) Greet(
	ctx context.Context,
	req *connect.Request[greetv1.GreetRequest],
) (*connect.Response[greetv1.GreetResponse], error) {
	log.Println("Request headers: ", req.Header())
	res := connect.NewResponse(&greetv1.GreetResponse{
		Greeting: fmt.Sprintf("Hello, %s!", req.Msg.Name),
	})
	res.Header().Set("Greet-Version", "v1")
	return res, nil
}
```

<Callout type="info">

The sample code is straight from the [getting started guide](https://connectrpc.com/docs/go/getting-started);
there are no Encore specific changes required here.

</Callout>

## Mount the service in Encore

Now we'll create an Encore [service struct](/docs/go/primitives/service-structs)
that initializes the Connect service, and a [raw endpoint](/docs/go/primitives/raw-endpoints)
that forwards incoming requests to the Connect service.

Add the file `greet/service.go` with the following contents:

```
-- greet/service.go --
package greet

import (
	"net/http"

	"encore.app/gen/greet/v1/greetv1connect"
	"golang.org/x/net/http2"
	"golang.org/x/net/http2/h2c"
)

//encore:service
type Service struct {
	routes http.Handler
}

//encore:api public raw path=/greet.v1.GreetService/*endpoint
func (s *Service) GreetService(w http.ResponseWriter, req *http.Request) {
	s.routes.ServeHTTP(w, req)
}

func initService() (*Service, error) {
	greeter := &GreetServer{}
	mux := http.NewServeMux()
	path, handler := greetv1connect.NewGreetServiceHandler(greeter)
	mux.Handle(path, handler)
	return &Service{routes: mux}, nil
}
```

That's it! We're ready to run the service and check that everything works.

## Run the service

Run the service with `encore run`:

```shell
$ encore run
```

Once it starts up, open a separate terminal and use `grpcurl` to call the service:

```shell
# Install grpcurl if you haven't already
$ go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest

# Call the service with grpcurl
grpcurl \
    -protoset <(buf build -o -) -plaintext \
    -d '{"name": "Jane"}' \
    localhost:4000 greet.v1.GreetService/Greet
{"greeting": "Hello, Jane!"} 

# Or call the service with curl
$ curl -H "Content-Type: application/json" -d '{"name": "Jane"}' http://localhost:4000/greet.v1.GreetService/Greet
{"greeting":"Hello, Jane!"}  # Expected response
```

If you see `{"greeting":"Hello, Jane!"}`, everything is working!

What's more, Encore automatically traces the incoming requests, and adds request logging and captures request metrics.
