javascripttypescriptnext.jsgrpcgrpc-node

Next.js grpc-node usage


I use gRPC but I have a problem initializing the service in Next.js app.

Goal: Create client service only once in app and use it in getServerSideProps (app doesn't use client-side routing).

For example, we have a service generated with grpc-tools (only available on SSR) and then I just want to initialize it somewhere. At first I thought it can be realized in a custom server.js:


const { credentials } = require('@grpc/grpc-js');
const express = require("express");
const next = require("next");

const { MyserviceClient } = require('./gen/myservice_grpc_pb');

const dev = process.env.NODE_ENV !== "production";

const app = next({ dev });
const handle = app.getRequestHandler();

// Init & Export
exports.myService = new MyserviceClient(
  'http://localhost:3000',
  credentials.createInsecure(),
);

(async () => {
  await app.prepare();
  const server = express();

  server.get("*", (req, res) => handle(req, res));

  server.listen(process.env.PORT, () => {
    console.log(`Listening at http://localhost:${process.env.PORT}`);
  });
})();

And then use it on the homepage, for example:

import React from 'react';

const { GetSmthRequest } = require('../gen/myservice_pb');
const { myService } = require('../server.js');

const IndexPage = () => (
  <div>
    <span>My HomePage</span>
  </div>
)

const getServerSideProps = async () => {
  const request = new GetSmthRequest();
  request.setSomeStuff('random');

  myService.getStmh(GetSmthRequest, (err, res) => {
    //...
  })

  return {
    props: {

    }
  }
}

export default IndexPage;

But for some reason it's not possible to initialize the client service in the server.js.


Also I tried doing it with next.config.js:

const { credentials } = require('@grpc/grpc-js');

const { MyserviceClient } = require('./gen/myservice_grpc_pb');

module.exports = {
  serverRuntimeConfig: {
    myService: new MyserviceClient(
      'http://localhost:3000',
      credentials.createInsecure(),
    ),
  },
};

This solution works, so I can use the service through serverRuntimeConfig, thereby initializing it only once in the entire application, but when I make a request somewhere using getServerSideProps, I get an error:

Request message serialization failure: Expected argument of type ...

Error explanation: (https://stackoverflow.com/a/50845069/9464680)

That error message indicates that message serialization (transformation of the message object passed to gRPC into binary data) failed. This generally happens because the message object doesn't match the expected message type or is otherwise invalid

Does anyone know why I am getting this error? It's also interesting to see some examples of using Next.js with grpc-node.


Solution

  • For such a case you can use Node.js global