---
# System prepended metadata

title: Basic GRPC Setup

---

# Basic GRPC Setup

## Requirements
* protoc 
* protoc-gen-go
```
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
```
* protoc-gen-go-grpc
```
 go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
```
* Get lib folder or collect it from protoc/include



Folder structure
- lib
- server
    - main.go
- proto
    - proto.proto
- client
    - main.go
- Makefile


## Writing protofile (proto/proto.proto)
```
syntax = "proto3";

package proto;

message Request {
}

message Response {
    string message = 1;
}

service Service {
    rpc Ping(Request) returns (Response);
}
```
## Writing Makefile
```
protogen-service:
	protoc -I./lib -I. \
	--go_out=plugins=grpc:. \
	./proto/proto.proto

```

if we run ```make protogen-service``` there should be a new generated file inside **proto** directory named ```proto.pb.go```

## Writing Server (server/main.go)

```
package main

import (
	"context"
	"net"

	"github.com/haquenafeem/msbasic/proto"
	"google.golang.org/grpc"
	"google.golang.org/grpc/reflection"
)

type server struct{}

func main() {
	listener, err := net.Listen("tcp", ":4042") // listens at this port
	if err != nil {
		panic(err)
	}

	srv := grpc.NewServer() // new grpc server
	proto.RegisterServiceServer(srv, &server{}) // registering server
	reflection.Register(srv) // reflecting 

	if e := srv.Serve(listener); e != nil { // serving
		panic(e)
	}

}

// implementing Ping function from proto (Service Interface in generated file)
func (s *server) Ping(ctx context.Context, request *proto.Request) (*proto.Response, error) {
	return &proto.Response{Message: "Ping from server"}, nil
}

```

## Writing Client (client/main.go)

```
package main

import (
	"context"
	"fmt"

	"github.com/haquenafeem/msbasic/proto"
	"google.golang.org/grpc"
)

func main() {
	// dials to get connection
	conn, err := grpc.Dial("localhost:4042", grpc.WithInsecure())
	if err != nil {
		panic(err)
	}

	// gets new service client from connection
	client := proto.NewServiceClient(conn)

	// requests for the method to call
	req := &proto.Request{}

	// calls the method using client
	response, err := client.Ping(context.Background(), req)
	if err != nil {
		panic(err)
	}

	// prints response
	fmt.Println(response.Message)
}


```

## Running
* Open a terminal -> run ```go run server/main.go```
* Open another terminal -> run ```go run client/main.go``` -> you should see ```Ping from server``` in the console.