resgateio / resgate

A Realtime API Gateway used with NATS to build REST, real time, and RPC APIs, where all your clients are synchronized seamlessly.
https://resgate.io
MIT License
685 stars 67 forks source link

Discussion: Microservices interacting with RES over http and websockets #31

Closed ghost closed 5 years ago

ghost commented 6 years ago

Proble: The problem with NATS is that is does not support Multi-Tenancy. Its been talked about being fixed and its unlikely to be. It also does not support on the fly config.

SO i was thinking that because there is a Client API for Res Clients to use, why cant there also be one for Microservices to use over HTTP and websockets ?

Why ?

  1. Enterprise patterns such as Security, metrics, logging, tracing etc can all be done at the Res Gateway level.
  2. You can secure Microservices so that they can only access parts of the NATS namespace ( loosely using this but i guess you know what i mean ).
ghost commented 6 years ago

Oh and i should ad that you can embed NATS in the server. Thankfully NATS people support this. Hence the RES Gateway is able to apple the security.

jirenius commented 6 years ago

I like how you think! :)

Yes, the security pattern in resgate allows Multi-tenancy, as it gives full control over what a client receives and can do. It was originally designed to be used for a cloud platform with multiple tenants with highly sensitive data.

Not sure I understand your suggestion, but you ideas sounds like an improved version of what I've imagined:

While the RES protocol is designed to work with web clients on the Internet, it may also serve for internal communication.

A setup (or cluster? I still haven't defined a name for it. Suggestions?) of resgate+gnatsd+(micro)services is to be seen a single server application. It has a single API endpoint (resgate), and from the outside (client), it cannot be distinguished from a big monolithic server.

To have multiple such "server applications/clusters" that communicates internally, where one microservice in one application acts as a RES client (over websockets) when getting data from another application, can really be beneficial, for all the reasons you've mentioned :)

What is missing? RES Client libraries in other languages.

Currently there is only the javascript ResClient. We need Go, Java, C#, etc.!

Embedding resgate with gnatsd

First I though. Naah. Embedding would prevent scaling of resgates.
But then again, if used for internal servers, it is highly unlikely that you will ever need multiple gateways. There are no tests on how many concurrent clients a single resgate can handle, but I would assume it has 5 digits. You seldom have that many internal connections anyway ;)

And since both resgate and gnatsd is written in Go, an embedded version would be easy to create. It would reduce internal server communication. Reduce number of running processes.

Yes.

It would work. đź‘Ť

ghost commented 6 years ago

If you embed NATS I believe you can still cluster. The leader electtion process will still take place. So you have a gateway with NATS and load balancer can sit in front ( of you can be tricky and use NATS as a load balancer and hand off to the least loaded gateway.


Yep I think you have got it. In terms of having to write a ton of clients I would just front NATS with a grpc. Then all clients can use it like dgraph does. The message for NATS is just a binary array of JSON. Now all other languages clients proxy code can 100% be generated using grpc. This will also work for web using grpc-web which can codegen to have, typescript or gopherjs and now gowasm.

Slot of the existing fragile code then goes away.

I think this really will work as I have done similar stuff before.

Now the front end fat clients can use grpc client proxy or the Https version of grpc too. For example I us golang grpc and generate my Dart grpc client proxies all the time. It idiot proof.

I might add that the orotobufs can be used to make a database layer and I have used that too. It's pretty cool but that's another day..

G

On Sun, 15 Jul 2018, 10:50 Samuel Jirénius, notifications@github.com wrote:

I like how you think! :)

Yes, the security pattern in resgate allows Multi-tenancy, as it gives full control over what a client receives and can do. It was originally designed to be used for a cloud platform with multiple tenants with highly sensitive data.

Not sure I understand your suggestion, but you ideas sounds like an improved version of what I've imagined:

While the RES protocol is designed to work with web clients on the Internet, it may also serve for internal communication.

A setup (or cluster? I still haven't defined a name for it. Suggestions?) of resgate+gnatsd+(micro)services is to be seen a single server application. It has a single API endpoint (resgate), and from the outside (client), it cannot be distinguished from a big monolithic server.

To have multiple such "server applications/clusters" that communicates internally, where one microservice in one application acts as a RES client (over websockets) when getting data from another application, can really be beneficial, for all the reasons you've mentioned :)

What is missing? RES Client libraries in other languages.

Currently there is only the javascript ResClient https://github.com/jirenius/resclient. We need Go, Java, C#, etc.! Embedding resgate with gnatsd

First I though. Naah. Embedding would prevent scaling of resgates. But then again, if used for internal servers, it is highly unlikely that you will ever need multiple gateways. There are no tests on how many concurrent clients a single resgate can handle, but I would assume it has 5 digits. You seldom have that many internal connections anyway ;)

And since both resgate and gnatsd is written in Go, an embedded version would be easy to create. It would reduce internal server communication. Reduce number of running processes.

Yes.

It would work. đź‘Ť

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/jirenius/resgate/issues/31#issuecomment-405076875, or mute the thread https://github.com/notifications/unsubscribe-auth/ATuCwijPiGurDCsRSXc4ngM00kL-9Zsrks5uGwJVgaJpZM4VOzii .

ghost commented 6 years ago

The user / domain types can be used in the Microservice server and clients still with grpc and NATS.

I think you just have to have a type name as part of the grpc contract. Then the wrapper code on server and client can check what type it is and Marshall the code from the binary array inside the protobuf --> the JSON type. All also easy to code gen.

Then a Microservice can just declare their types and we codegen a marshaller for this types for the resgate client proxy code to use when wrapping and unwrapping.

Wait . But in the resgateway it does NOT give too hoots what is the bi ary array JSON data right ? It just moves the data around to the respective parties via NATS. So your all good in that resgate stays agnostic and does not need to Marshall / unmarsgall the binary arrays.

I think it will work ... Famous last words :)

jirenius commented 6 years ago

After re-reading a few times, I am still uncertain on the exact setup, and how it would work.

There are a few things to consider:

NATS Server clustering
NATS Server clustering support for resgate has yet to be investigated. Resgate currently is built to stop if connection is lost, but if it instead would act upon a reconnect, the ReconnectHandler could just mark all cached resources as stale, making a "system.reset" for all its cached resources, having them resynched without having to disconnect the clients and forcing them to resync instead.

Resgate cache updating
Resgate does give a hoot about the JSON data. First of all, the service and client protocol are different. The service protocol is a pub/sub protocol with a separate topic/subject, not part of the payload. The client protocol is a JSON RPC-like protocol, where the method/subject/event name is part of the payload. So, even for messages such as a custom event, which has no side effects in resgate, the binary JSON array still need to be repackaged from service to client format.

And then we have events that describes resource mutations, change, add, and remove. These needs to be decoded by resgate in order to keep its own cache up-to-date. This requires resgate to be able to decode an object without really knowing the type of each property prehand, as values might be any type of primitive, or resource references.

If Protobuf can handle some type of generics values, some sort of RawMessage value, then it can be done. Otherwise I have difficulties to see how it would work.

Or have I misunderstood what you try to achieve?

jirenius commented 5 years ago

Closing topic