doug-martin / nestjs-query

Easy CRUD for GraphQL.
https://doug-martin.github.io/nestjs-query
MIT License
821 stars 142 forks source link

[Feature] Possible `@nestjs-query/grpc` #719

Open vabatta opened 3 years ago

vabatta commented 3 years ago

Is your feature request related to a problem? Please describe. Not really related to a problem. The initial idea was to use Federation but Apollo Federation is not fully ready yet (and most probably won't be for some time coming) and we really need subscriptions. Other implementations exists for Federated subscriptions but not integrated into NestJS. With this said, we were thinking of using a more traditional approach where each microservice manages the data of its domain and communicate to all other services via gRPC. The only exposed API gateway is then built up with GraphQL with nestjs-query. This ticket is to exploring and understanding the effort for this feature.

Have you read the Contributing Guidelines?

Yes.

Describe the solution you'd like Having an out of the box ExternalQueryService which can call external QueryService via gRPC. The idea would be that API gateway accepts in ServiceClass an ExternalQueryService which does the work of communicating to the actual QueryService in another microservice via gRPC.

Describe alternatives you've considered Our investigation lead us to having a look into these technologies as alternatives:

And these for a possible wrapping:

psteinroe commented 3 years ago

Great idea! Did you make any progress here? Our use case is that we have an externally facing GraphQL API and for inter-service communication we want to use grpc, and it would be super efficient if we could simply expose parts of the GraphQL API also as a grpc service for inter-service communication.

smolinari commented 3 years ago

I personally don't understand how this can work. Well, at least in an automated way. Correct me if I am wrong, but gRPC with protobufs will generate a set of methods ( the procedure calls) for the client to work with the microservice(s). How would nestjs-query know what those methods look like or what they can be used for?

Scott

koolamusic commented 3 years ago

Now this is interesting, though I think the approach outlined in this issue might not be very applicable. The way I see it, GRPC would be a replacement for the persistence layer, however the API Gateway would be responsible for

  1. Defining the DTOs
  2. Creating the Services either by extending (ProxyQueryService or NoOpQueryService) and overriding the methods to call the GRPC endpoints responsible for performing the actions, so that something like

 // Override all the create, update, and delete methods to add the timed logging functionality
  createMany(items: C[]): Promise<DTO[]> {
    return this.timedLog(`create many [itemCount=${items.length}]`, () => super.createMany(items));
  }

Will instead work in a manner like


 // Override all the create, update, and delete methods to add the timed logging functionality
  createMany(items: C[]): Promise<DTO[]> {
    return this.rpcClient.createMany(items).toPromise()
  }

The rpc client here is from the Nestjs ClientProxyFactory This might be a bit more work, since you will still need to do something almost similar with your service Entities.

So I am guessing the question would be how to leverage, the BaseServices and maybe Assemblers to achieve something similar, but that isn't the goals of this package, because I believe reducing the whole repetition was the goal,

However if we can achieve the same thing we did with persistence layers with transport layers without much over-head, that would be a win as well

koolamusic commented 3 years ago

On a second thought, following this topic. There is a possibility that exists by leveraging the .protobuf and Entity to:

This is based of the assumption this will be a Hybrid application (thanks to Nestjs) or a monorepo which multiple microservics and a shared library (can be setup in nestjs too) where the proto and entity can be shared.

The hybrid example would be an easy way to introduce the concept, I believe.

EDIT: proto files can be generated the same way graphql schema files, my understanding is that we already generate resolvers and base services for the ORM, so by leveraging the DTO and model we can do same for grpc, strictly in Nestjs by

Then we use a module to instantiate the client etc and this does not have to cater for ExternalQueryService because the same DTO mappers are used in a grpc context, but I also see how this solves an entirely different suite of problems which is beyond just graphql, but caters to the needs of query in nestjs-query FYI .proto files are just about the same set of strong type definitions similar in a graphql schema