Learn how to build an RPC (remote procedure call) server in Go and how to make calls to procedures on the server via a client written in Node.

Introduction

RPC (remote procedure call), in simple terms, is a protocol that is used for client-server applications which allows software developers to request a procedure or a function call to a remote server. In this tutorial, you will be learning how to build an RPC server in Go along with an RPC client in Node.js.

Prerequisites

You’ll need:

  • Go installed on your local machine
  • Node installed on your local machine
  • Protocol buffer installed on your local machine

Objectives

In this article, we will be building a chat RPC server to send a message and return descriptive details of a user. The send message procedure will accept the message body while the other will accept the user’s name and age.

Create server

In this step, you will be building your RPC server. Start by creating a new project directory by running:

mkdir rpc-server

Change directory to the newly created folder:

cd rpc-server

Configure protocol buffer

A protocol buffer is a data format created by Google to enable developers to generate source code based on the data and service specified for any programming language.

Create a proto file named chat.proto:

touch chat.proto

Open chat.proto with your desired editor and paste the following code:

syntax = "proto3";

package chat;

message Message {
  string body = 1;
}

message Details {
  string name = 1;
  int32 age = 2;
}

message Response {
  string body = 1;
}

service ChatService {
  rpc SayHello(Message) returns (Response) {}
  rpc GetDetails(Details) returns (Response) {}
}

Let us go through what each block does:

syntax = "proto3";

This specifies what version of protobuf we intend to write.

message Message {
  string body = 1;
}

This declares a Message data object that can only contain a string element with the tag body.

message Details {
  string name = 1;
  int32 age = 2;
}

This declares a Details data object that can only contain a string element with the tagged name and an integer element with the tagged age.

message Response {
  string body = 1;
}

This declares a Response data object that can only contain a string element with the tag body.

service ChatService {
  rpc SayHello(Message) returns (Message) {}
  rpc GetDetails(Details) returns (Details) {}
}

This declares a new service called ChatService which will contain two methods, SayHello method which accepts the Message data object and returns Response and the GetDetails method which accepts Details and returns Response back as well. Save and exit the file.

Note: You can learn more about protobuf here.

Generate Go code

We will generate a protocol buffer Go code based on the proto file we wrote in the previous step. While still being in the rpc-server directory, run the following command:

 mkdir chat

This will generate a new folder named chat within the rpc-server directory. This is where you place our generated Go code along with the implementation of your chat.proto file. Run the following to generate your go code off your chat.proto file:

protoc --go_out=plugins=grpc:chat chat.proto

Note: You can learn more about Go generated code here.

This will generate a new file named chat.pb.go in the chat directory created earlier.

Note: Do not modify the contents of _chat.pb.go_.

Implement methods

In this step, we will be implementing the methods in ChatService as defined in chat.proto.

Create a new file named chat.go:

touch chat.go

Open chat.go with your desired editor and paste the following code:

package chat

import (
    "fmt"
    "golang.org/x/net/context"
    "log"
)

type Server struct{}

func (s *Server) SayHello(ctx context.Context, message *Message) (*Response, error) {
    log.Println("SayHello Called")
    return &Response{Body: fmt.Sprintf("New Message: %s", message.Body)}, nil
}

func (s *Server) GetDetails(ctx context.Context, message *Details) (*Response, error) {
    log.Println("GetDetails Called")
    return &Response{Body: fmt.Sprintf("Your name is %s and you're %d years old", message.Name, message.Age)}, nil
}

Let me break down the essentials:

type Server struct{}

This acts as a server interface to this ChatService implementation, we will be using this later on to plug into the RPC server.

The first function implements the SayHello function, when called it will log

SayHello Called to the console while returning the Response object along with the message body passed to it back to the client.

The second function implements the GetDetails function, when called it will log

GetDetails Called to console while returning the Response object along with a custom message containing the data passed back to the client.

Both methods return error and a pointer reference of Response which exists as a struct in the chat.pb.go file generated based on what we defined in chat.proto.

Note: Implemented methods must return a pointer reference of what was defined in the _proto_ declaration and error.

#go #node #web-development #developer

How to Build an RPC Server in Go along with an RPC Client in Node.js
6.55 GEEK