dgraph-io / dgraph

The high-performance database for modern applications
https://dgraph.io
Other
20.3k stars 1.49k forks source link

[FEATURE]: Simple gRPC support for GraphQL #8697

Closed ruidscampos closed 1 month ago

ruidscampos commented 1 year ago

Use case

For GraphQL access, when the communication with Dgraph is done via an internal microservice instead of an external client, would be great to do it with gRPC instead of HTTP and save ms on the communication.

gRPC supports bidirectional streaming, reducing the overhead imposed by continuous connections, and if protobufs where used as a basic way of communication it sould further reduce the overhead of the message and communication.

This is useful on an operational platform where thousands of users are simultaneously accessing data for both reads and writes, and IoT devices are feeding information every few seconds.

Links to Discuss, RFC or previous Issues and PRs

No response

Links to examples and research

No response

Current state

No response

Solution proposal

A simple solution sould suffice as a starting point, with only the content and variables. This can later be improved into something more comprehensive.

Ideally this would support a bidirectional stream that is started once by the microservice and can be reused for multiple operations, reducing the overhead of starting multiple connections and would work great for subscriptions.

Using this should help save a few ms in each operation, which is quite an important thing on a platform with thousands of simultaneous users and IoT devices.

Example protobuf: message Query { bytes query = 1; bytes variables = 2; } message Mutation { bytes mutation = 1; bytes variables = 2; } message Subscription { bytes subscription = 1; bytes variables = 2; } message Response { bytes content = 1; } message PartialResponse { bytes content = 1; }

Example grpc: service DgraphGrpc { rpc Query(Query) returns (Response) {} rpc QueryStream(stream Query) returns (stream Response) {} rpc Mutation(Mutation) returns (Response) {} rpc MutationStream(stream Mutation) returns (stream Response) {} rpc Subscription(Subscription) returns (Response) {} rpc SubscriptionStream(stream Subscription) returns (stream Response) {} }

Another interesting solution would be to return the content on-demand via a stream as soon as it's read instead of bundling in a response before sending: service DgraphGrpc { rpc Query(Query) returns (stream PartialResponse) {} rpc QueryStream(stream Query) returns (stream PartialResponse) {} rpc Mutation(Mutation) returns (stream PartialResponse) {} rpc MutationStream(stream Mutation) returns (stream PartialResponse) {} rpc Subscription(Subscription) returns (stream PartialResponse) {} rpc SubscriptionStream(stream Subscription) returns (stream PartialResponse) {} }

Additional Information

No response

rderbier commented 1 year ago

Prove the performance gain. To investigate. Include Subscription ( which is websocket).

What about the GraphQL clients on the market: will they support gRPC.

github-actions[bot] commented 1 month ago

This issue has been stale for 60 days and will be closed automatically in 7 days. Comment to keep it open.