Solution 3: Working with gRPC
Explore how to implement gRPC services in Go by creating a RESTful server using the Gin framework that interacts with a gRPC server via protocol buffers. Understand setting up endpoints that call gRPC methods, establish connections with grpc.Dial, and handle JSON responses for data exchange.
We'll cover the following...
We'll cover the following...
Solution
Here is a RESTful service that uses gRPC for data exchange. To execute the RESTful service:
Open a new terminal window and execute the
rServer.gocode using the following commands:
export GOROOT=/usr/local/go; export GOPATH=$HOME/go; export PATH=$GOPATH/bin:$GOROOT/bin:$PATH; cd usercode;go run rServer.go
Then, open another terminal window and execute the following
curlcommands:
# curl http://localhost:8081/datetime# curl http://localhost:8081/randompassword# curl http://localhost:8081/randominteger
package main
import (
"context"
"github.com/gin-gonic/gin"
"google.golang.org/grpc"
"log"
"net/http"
"os"
"github.com/Educative-Content/protoapi"
)
var grpcServerAddress = "localhost:8082"
func main() {
router := gin.Default()
// Initialize a gRPC connection to the server
conn, err := grpc.Dial(grpcServerAddress, grpc.WithInsecure())
if err != nil {
log.Fatalf("Failed to connect to gRPC server: %v", err)
}
defer conn.Close()
client := protoapi.NewRandomClient(conn)
// Define RESTful API endpoints
router.GET("/datetime", func(c *gin.Context) {
ctx := context.Background()
response, err := client.GetDate(ctx, &protoapi.RequestDateTime{})
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"datetime": response.Value})
})
router.GET("/randompassword", func(c *gin.Context) {
ctx := context.Background()
response, err := client.GetRandomPass(ctx, &protoapi.RequestPass{Seed: 100, Length: 8})
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"password": response.Password})
})
router.GET("/randominteger", func(c *gin.Context) {
ctx := context.Background()
response, err := client.GetRandom(ctx, &protoapi.RandomParams{Seed: 100, Place: 1})
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"integer": response.Value})
})
port := getPort()
router.Run(":" + port)
}
func getPort() string {
if len(os.Args) > 1 {
return os.Args[1]
}
return "8081" // Default port
}
gServer.go and rServer,go