Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auto-generated TypeScript service definition does not work with addService #1766

Closed
jsholzer opened this issue Apr 28, 2021 · 7 comments
Closed

Comments

@jsholzer
Copy link

jsholzer commented Apr 28, 2021

I recently started checking out gRPC and wanted to implement a basic client and server in TypeScript. This ultimately led me to the @grpc/proto-loader package. When generating the TypeScript typings for the service/proto, the service definition interface that was generated was incompatible with the grpc.Server.addService method. I'm currently using a protobuf service based on the "helloworld" example from the official gRPC repo.

Problem description

The service definition interface generated by the proto-loader-gen-types utility is incompatible with the addService method of the gRPC server instance.

The error given by the TypeScript compiler, in my case, is as follows:

Argument of type 'GreeterDefinition' is not assignable to parameter of type 'ServiceDefinition<UntypedServiceImplementation>'.
  Index signature is missing in type 'GreeterDefinition'.ts(2345)

Protobuf service definition (helloworld.proto):

syntax = "proto3";

package helloworld;

// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {}

  // Sends another greeting
  rpc SayHelloAgain (HelloRequest) returns (HelloReply);
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings
message HelloReply {
  string message = 1;
}

Auto-generated service definition interface:

export interface GreeterDefinition {
  SayHello: MethodDefinition<_helloworld_HelloRequest, _helloworld_HelloReply, _helloworld_HelloRequest__Output, _helloworld_HelloReply__Output>
  SayHelloAgain: MethodDefinition<_helloworld_HelloRequest, _helloworld_HelloReply, _helloworld_HelloRequest__Output, _helloworld_HelloReply__Output>
}

I was able to resolve the issue by manually modifying the service definition interface, extending grpc.ServiceDefinition, as follows:

export interface GreeterDefinition extends grpc.ServiceDefinition {
  ...
}

Reproduction steps

  1. Use the proto-loader-gen-types utility to generate typings:
$(npm bin)/proto-loader-gen-types --longs=String --enums=String --defaults --oneofs --grpcLib=@grpc/grpc-js --outDir=proto/ proto/helloworld.proto
  1. Use the auto-generated typings to create a gRPC server
import * as grpc from "@grpc/grpc-js";
import * as protoLoader from "@grpc/proto-loader";
import { ProtoGrpcType } from "./proto/helloworld";
import { GreeterHandlers } from './proto/helloworld/Greeter';
import { HelloRequest } from "./proto/helloworld/HelloRequest";
import { HelloReply } from "./proto/helloworld/HelloReply";

const greeterServer: GreeterHandlers = {
    SayHello(call: grpc.ServerUnaryCall<HelloRequest, HelloReply>, callback: grpc.sendUnaryData<HelloReply>)
    {
        callback(null, {message: `Hello ${call.request.name}`});
    },

    SayHelloAgain(call: grpc.ServerUnaryCall<HelloRequest, HelloReply>, callback: grpc.sendUnaryData<HelloReply>)
    {
        callback(null, {message: `Hello again ${call.request.name}`});
    }
}

const PROTO_PATH = `${__dirname}/proto/helloworld.proto`;
const packageDefinition = protoLoader.loadSync(PROTO_PATH);
const proto = (grpc.loadPackageDefinition(packageDefinition) as unknown) as ProtoGrpcType;
const server = new grpc.Server();

server.addService(proto.helloworld.Greeter.service, greeterServer);
server.bindAsync("0.0.0.0:50051", grpc.ServerCredentials.createInsecure(), (err, port) => {
    if (err) throw err;
    
    console.log(`Server started, listening on port ${port}`);
    server.start();
});

Environment

  • Windows 10 64-bit
  • Node version 14.16.1
  • @grpc/grpc-js version 1.2.12
  • @grpc/proto-loader version 0.6.1
@gtolarc
Copy link

gtolarc commented May 24, 2021

Does not work on grpc other than @grpc/grpc-js.

  • @grpc/proto-loader: 0.6.2 (No problem in version 0.6.1)
  • grpc: 1.24.10

@murgatroid99
Copy link
Member

What exactly are you trying to do, and what error are you getting?

@gtolarc
Copy link

gtolarc commented Jun 2, 2021

스크린샷 2021-06-02 오전 9 49 41
In 0.6.1, it was created as 'export interface AuthDefinition {'.

@murgatroid99
Copy link
Member

What is the error? That doesn't show any error.

@gtolarc
Copy link

gtolarc commented Jun 2, 2021

What is the error? That doesn't show any error.

really??

@murgatroid99
Copy link
Member

Oh, I'm sorry, I didn't see that that error message was separate from the type definition information. I will look into fixing that.

@murgatroid99
Copy link
Member

This has been fixed in grpc version 1.24.11.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants