Next.js using Go RPC Server for your API

Outline


This post provides a tutorial on setting up a Go RPC Server to server your API to your Next.js application. Part 1 covers setting up a Go RPC server to handle HTTP requests, including creating a client that connects to the server and calls the Add method remotely. Part 2 covers how to use Next.js to connect to the Go RPC server, including examples in both JavaScript and TypeScript.

💡 RPC (Remote Procedure Call) is a popular way to build distributed systems, where a client can call a function or method on a remote server as if it were calling a local function.

Prerequisites


The Server


Here we outline how to set up a Go RPC server to handle HTTP requests. It provides an example of a simple RPC server in Go that defines a Add method to add two integers. The tutorial also covers testing the RPC server, including creating a client that dials the server and calls the Add method remotely.

💡 In Go, you can create an RPC server using the standard library package net/rpc

Description


Here are two examples: creating a simple RPC server in Go and creating a simple project to test its functionality.

💡 Go is a programming language created at Google in 2009 by Robert Griesemer, Rob Pike, and Ken Thompson. It is a statically typed, compiled language designed to be efficient, expressive, and easy to read and write. Go is known for its simplicity, high performance, and built-in support for concurrency. It is often used for building web servers, network tools, and command-line utilities.

Server Code Example


Create a new Go project. Open a Console, Terminal, or PowerShell window.

mkdir project-name
cd project-name
go mod init project-name
code .

Here’s an example of how to create a simple RPC server in Go:

package main

import (
    "fmt"
    "net"
    "net/rpc"
)
type Args struct {
    A, B int
}
type Arith int
func (t *Arith) Add(args *Args, reply *int) error {
    *reply = args.A + args.B
    return nil
}
func main() {
    arith := new(Arith)
    rpc.Register(arith)
    rpc.HandleHTTP()
    listener, err := net.Listen("tcp", ":1234")
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    fmt.Println("RPC server listening on port 1234...")
    err = http.Serve(listener, nil)
    if err != nil {
        fmt.Println("Error:", err)
    }
}

Code Summary


In this example, we define a Args struct to hold the arguments for the Add method of the Arith type. We also define the Arith class, which implements the Add method. This method takes a pointer to an Args struct and a pointer to an integer, and adds the two integers in the Args struct, storing the result in the integer pointed to by the second argument.

Next, we create an instance of the Arith type and register it with the rpc package. We also call rpc.HandleHTTP to write the RPC handler with the http package.

We then create a listener on port 1234 and start listening for incoming connections. Finally, we start the HTTP server and handle any errors that occur.

Run our server:

go run .

Test Code Example


Let's create our test project:

mkdir test-project-name
cd test-project-name
go mod init test-project-name
code .

To test the RPC server, you can create a client that calls the Add method remotely:

package main

import (
    "fmt"
    "net/rpc"
)
type Args struct {
    A, B int
}
func main() {
    client, err := rpc.DialHTTP("tcp", "localhost:1234")
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    args := &Args{7, 8}
    var reply int
    err = client.Call("Arith.Add", args, &reply)
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    fmt.Printf("%d + %d = %d\\n", args.A, args.B, reply)
}

Code Summary


In this example, we create a client that calls the RPC server at localhost:1234. We then create a Args struct with values of 7 and 8 and a variable to hold the result of the remote Add method.

We call client.Call to invoke the Add method remotely, passing in the method name, the Args struct, and a pointer to the result variable. If there are no errors, we print the result.

Next.js


Now we cover how to use Next.js with a Go RPC server. It provides examples of how to create a simple Next.js project to test it. The tutorial also covers creating an API route that connects to the RPC server, makes an RPC client, and calls an RPC method with arguments. The tutorial includes examples in both JavaScript and TypeScript.

Using JavaScript

💡 JavaScript is a programming language that is often used to build interactive web applications. It was created in 1995 by Brendan Eich while he was working at Netscape Communications Corporation. JavaScript is a high-level, dynamic, and interpreted language that is designed to be easy to learn and use. It is often used in conjunction with HTML and CSS to add interactivity to web pages. Some popular uses of JavaScript include creating dynamic user interfaces, validating form data, and making asynchronous requests to servers.

Scroll down to view the TypeScript version of this section.

Description


We can create an API route that connects to an RPC server running, produces an RPC client, and calls the add method with arguments 2 and 3. The result is returned as JSON.

Project Creation


npm create next-app app-name
cd app-name
code .

Create a new file in your Next.js project’s pages/api directory. For example, you could create a file called. my-rpc.js.

Import Modules


  1. In the new file, import the net and rpc modules:
const net = require('net');
const rpc = require('rpc');

Define RPC Methods


  1. Define your RPC methods. For example:
const add = (a, b) => {
  return a + b;
};

Create an instance of the RPC Server


  1. Create a new RPC server instance and register your methods:
const server = net.createServer(function (stream) {
  const myRpc = rpc.createRpcServer(stream);
  myRpc.register('add', add);
});

Export API Route and handle incoming requests


  1. Finally, export an API route that creates a new connection to the RPC server and handles incoming requests:
export default async function handler(req, res) {
  // Connect to the RPC server
  const connection = net.connect(5000, 'localhost');
  // Create an RPC client
  const myRpc = rpc.createRpcClient(connection);
  // Call the "add" method with arguments 2 and 3
  const result = await myRpc.promise('add', 2, 3);
  // Return the result as JSON
  res.status(200).json({ result });
}

Summary


In this example, we’ve created an API route that connects to an RPC server running, produces an RPC client, and calls the add method with arguments 2 and 3. The result is returned as JSON.

Note that this is just a simple example of how to use RPC in Next.js with JavaScript. In a real-world application, you should add more error handling, authentication, or other features.

Using TypeScript

💡 TypeScript is a superset of JavaScript that adds optional static typing to the language. It was created by Microsoft in 2012 and has gained popularity in recent years, particularly in the development of large-scale web applications. TypeScript code is transpiled to standard JavaScript, so it can run in any browser or JavaScript environment. Some of the benefits of using TypeScript include improved code quality and maintainability, better tooling support, and enhanced developer productivity.

Description


We can create an API route that connects to an RPC server running, produces an RPC client, and calls the add method with arguments 2 and 3. The result is returned as JSON.

Project Creation


npm create next-app --typescript app-name
cd app-name
code .

Create a new file in your Next.js project’s pages/api directory. For example, you could create a file called. my-rpc.ts.

Import Modules


  1. In the new file, import the net and rpc modules:
import * as net from 'net';
import * as rpc from 'rpc';

Define RPC Methods


  1. Define your RPC methods. For example:
const add = (a: number, b: number): number => {
  return a + b;
};

Create an instance of the RPC Server


  1. Create a new instance of the RPC server and register your methods:
const server = net.createServer(function (stream) {
  const myRpc = rpc.createRpcServer(stream);
  myRpc.register('add', add);
});

Export API Route and handle incoming requests


  1. Finally, export an API route that creates a new connection to the RPC server and handles incoming requests:
import { NextApiRequest, NextApiResponse } from 'next';

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
  // Connect to the RPC server
  const connection = net.connect(5000, 'localhost');
  // Create an RPC client
  const myRpc = rpc.createRpcClient(connection);
  // Call the "add" method with arguments 2 and 3
  const result = await myRpc.promise('add', 2, 3);
  // Return the result as JSON
  res.status(200).json({ result });
}

Summary


In this example, we’ve created an API route that connects to an RPC server running, produces an RPC client, and calls the add method with arguments 2 and 3. The result is returned as JSON.

Note that this is just a simple example of how to use RPC in Next.js with TypeScript. In a real-world application, you might want to add more error handling, authentication, or other features.