# 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.