agreatfool / grpc_tools_node_protoc_ts

Generate TypeScript d.ts definitions for generated js files from grpc_tools_node_protoc

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Feature request: single interface for servers.

majelbstoat opened this issue · comments

Would you be open to adding an interface that gathered all the server methods into one place? From your example, something like:

interface BookService {
  getBook: handleUnaryCall<GetBookRequest, Book>
  getBooks: handleBidiStreamingCall<GetBookRequest, Book>
  // ...
}

It would be nice to be able to do:

class Service implements BookService {
  getBook: (call: ServerUnaryCall<OtherRequest>, callback: sendUnaryData<Book>) { // Error
  }
}

and get type-checking on all the method signatures inside it, whilst having access to member variables. I'm doing this myself for a couple of services, and it seems generally applicable and useful.

Sorry. I did't get your point.

Current the d.ts codes of file *_pb.d.ts, comes accordingly from the official js codes generated via grpc_tools_node_protoc. There is no self defined interfaces & methods, etc.

I'm ok to add some useful interfaces. And It's better to have a sample to help understanding. Thank you.

Oh, sorry, I was trying to provide a sample, based on https://github.com/agreatfool/grpc_tools_node_protoc_ts/tree/master/examples/src:

interface IBookServiceClass {
  getBook: handleUnaryCall<GetBookRequest, Book>
  getBooks: handleBidiStreamingCall<GetBookRequest, Book>
  getGreatestBook: handleServerStreamingCall<GetBookRequest, Book>
  // etc..
}

To be clear, yes, this would be an additional interface for convenience, not a replacement for existing ones.

Ok, I just got your point. You want to add a server signature just like the client ones.

So the next question is how would you use this new added signature?

I guess, the example would be, from:

server.addService(BookServiceService, {
getBook: (call: grpc.ServerUnaryCall<GetBookRequest>, callback: grpc.sendUnaryData<Book>) => {
const book = new Book();
book.setTitle("DefaultBook");
book.setAuthor("DefaultAuthor");
log(`[getBook] Done: ${JSON.stringify(book.toObject())}`);
callback(null, book);
},
getBooks: (call: grpc.ServerDuplexStream<GetBookRequest, Book>) => {

to:

  const getBookImpl: IBookServiceClass.getBook = (call: grpc.ServerUnaryCall<GetBookRequest>, callback: grpc.sendUnaryData<Book>) => {
      const book = new Book();

      book.setTitle("DefaultBook");
      book.setAuthor("DefaultAuthor");

      log(`[getBook] Done: ${JSON.stringify(book.toObject())}`);
      callback(null, book);
  };

  server.addService(BookServiceService, {
    getBook: getBookImpl,
    getBooks: (call: grpc.ServerDuplexStream<GetBookRequest, Book>) => {

Is this the use case you want?

My personal preference would be to implement the handler as a class, but yes, that’s it :)

class BookServiceHandler implements IBookServiceClass {
  getBook(call: ServerUnaryCall<GetBookRequest>, callback: sendUnaryData<Book>) {
  }
}

// ...

server.addService(BookServiceService, new BookServiceHandler())

That's interesting. Currently the support of the client codes is good, since the js codes generated is so. And yes, the support of server side code is not so automatically.

Thank you for your suggestion. Let me dig more deeply into it.

Done. Please check the latest version 2.3.0.

Wow! Works great, thanks so much! :)