ts-proto icon indicating copy to clipboard operation
ts-proto copied to clipboard

Can you somehow output both nestjs and grpc-js proto for a given proto file?

Open gitn00b1337 opened this issue 2 years ago • 2 comments

I've got a load of microservices written with nestjs. I have now added a remix web app (this has it's own server side, like nextjs). I wanted to send requests using grpc-js and continue using the generated code from ts-proto but I've hidden a snag that I can't work out.

protoc --ts_proto_opt=nestJs=true --ts_proto_opt=esModuleInterop=true --ts_proto_opt=returnObservable=false --ts_proto_opt=outputServices=grpc-js --ts_proto_opt=outputClientImpl=grpc-js --plugin=./node_modules/.bin/protoc-gen-ts_proto --ts_proto_out=./src/grpc/types ./src/grpc/protos/auth-schemas.proto -I ./src/grpc/protos

Here I use the nestJs=true flag for creating the ts files. It seems that this overrides everything else. If I remove that flag I suddenly have all the grpc-js code but obviously no nestjs.

I thought about generating 2 ts files: one .nestjs and one .client but i also couldn't see how to rename the files during generation without also having to add a third command inbetween to do so outside ts-proto. Doing this would mean 3x the commands and I have a lot of microservices I'd need to do this for. Is there any other way? My expectation was adding --ts_proto_opt=outputServices=grpc-js would just append grpc-js specific code. I've seen that actually it provides the nestjs 8 support which migrated to grpc-js.

gitn00b1337 avatar May 02 '22 03:05 gitn00b1337

Hey @gitn00b1337 yeah, nestJs is sort of a meta-flag for other things. You can see how it's handled here:

https://github.com/stephenh/ts-proto/blob/main/src/options.ts#L120

Oh shoot, yeah and then here:

https://github.com/stephenh/ts-proto/blob/main/src/main.ts#L201

So we do have a big "if nestJs" that will skip the other stuff. :-/

Yeah, we should clean this up to remove that "if nestJs" and try to get the config options to be more mutli-assignment ie, i.e. outputServices=nestJs,grpc-js / outputClientImpl=grpc-js,nestJs.

We could probably do that by changing out options.ts works insofar as instead of checking nestJs first, we'd do all the normal option parsing, and then if nestJs is enabled, just do like outputServices.push("nestJs") / outputClientimpl.push("nestJs")...

And then clean up that main.ts if/else...

If you'd like to submit a PR for this, that'd be great. Thanks!

stephenh avatar May 09 '22 14:05 stephenh

You could potentially resolve your issue with multi-file generation by using the fileSuffix option, allowing you to generate grpc-js files as normal and then nest files like file-name.nest.ts.

An example of this utilizing Buf would look like this:

buf.gen.yaml

version: v1
managed:
  enabled: true
plugins:
  - name: grpc-js
    out: gen/proto/grpc-js
    strategy: all
    path: ../node_modules/ts-proto/protoc-gen-ts_proto
    opt:
      ...
  - name: nest
    out: gen/proto/nest
    strategy: all
    path: ../node_modules/ts-proto/protoc-gen-ts_proto
    opt:
      - env=node
      - nestJs=true
      - fileSuffix=.nest
      ...

The nice thing about this option is that it could generate both types of output files for all your microservices in 1 command.

Jake-RoundrockIO avatar May 19 '22 20:05 Jake-RoundrockIO