Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convey configuration strategy #13

Open
gitblit opened this issue Oct 30, 2019 · 5 comments
Open

Convey configuration strategy #13

gitblit opened this issue Oct 30, 2019 · 5 comments

Comments

@gitblit
Copy link

gitblit commented Oct 30, 2019

I watched your Convey walkthrough last weekend. Very interesting! I like how you are stitching together all these components into an semi-opinionated, cohesive, scalable story. I am particularly interested in how Entrada fits into Convey.

Have you considered: instead of (or in addition to) declaring a complete configuration in YML, having Convey microservices register with an Entrada instance at runtime/startup? Maybe you decorate/annotate handlers for Entrada registration.

It's not a fully formed thought in my head but I'm trying to think of ways this could be a little more dynamic.

@spetz
Copy link
Member

spetz commented Oct 30, 2019

Hey,
Thank you for the kind words, really happy to hear that :).

Just to clarify, Ntrada is a different project than Convey. It's an API Gateway that can be run seamlessly e.g. via Docker as well as used as a custom library if you're willing to extend it with your own C# code. Basically, you could use Convey packages along with Ntrada (e.g. tracing, persistence, monitoring etc.), but that's pretty much it.

If I understand you correctly, you're asking whether it would be possible to create a Convey extension (let's call it Ntrada integration), so that the API Gateway itself wouldn't be configured via YML or any other type file, but based on the microservices in your solution, it would configure itself dynamically (something like Fabio does via Consul tags).

I think it's a really great idea and actually there would be no need to use Convey at all. It could be a standalone Nuget package that is able to register within Ntrada on its own (via Web API or so), or even better, it could be sidecar/proxy (something like Envoy), that could be run next to your microservice (written in any language) and it'd register the service instances into the API Gateway.

Let me know if that's what you were thinking of.

@gitblit
Copy link
Author

gitblit commented Oct 30, 2019

Ntrada is a different project than Convey

Understood.

it would configure itself dynamically

Yes, that's the idea. Make the gateway dynamically responsive to the services it actually proxies rather than being declarative where configuration must be double-maintained.

The sidecar design is interesting, I can see what problems it solves but I'm not totally convinced to use it myself. It feels like yet another layer of DevOps complexity. The sidecar pattern is what Microsoft is promoting with their recently announced Dapr project.

@spetz
Copy link
Member

spetz commented Oct 30, 2019

That makes a lot of sense, and whether it'd be a sidecar (Dapr is interesting, yet didn't have time to play with it yet) or a simple HTTP request it pretty much boils down to the same Web API call.

There are still (at least) a few questions:

  • Should microservices use Swagger/Open API for endpoints definitions? That's pretty much a standard nowadays, however, if we would like to achieve more complex configuration (sending commands via message broker, request transformation, etc.) then it'd make more sense to use either the current Ntrada format or something similar. Actually, the question is - should the microservice just define its endpoints or also the way how such endpoints such be visible (and handled) from the end-user perspective, for example, HTTP POST to /users endpoint being part of users-service should be sent via RabbitMQ and that's what API Gateway would be responsible for doing.

  • Service discovery - given that we have multiple instances of the same microservice, should API Gateway care about this it all? It would be probably better to use Consul, Eureka or built-in Docker/Kubernetes service registry/discovery/DNS. The API Gateway should only take care of updating its configuration dynamically.

  • Authentication & authorization - each microservice would define required claims for particular endpoints, but the overall access validation should be probably performed on the API Gateway side.

@gitblit
Copy link
Author

gitblit commented Oct 30, 2019

Hah. All good questions. That's why this is your project, not mine. :)

  1. The microservice already defines how it can communicate. The Entrada config is a replication of that (possibly a subset if you are building both restful apis and message bus capability). The microservice could specify it's preferred Entrada delegation mechanism probably with a default for the microservice with optional discrete overrides per handler?
    [Entrada(Bus = true, Endpoint = true)] // terrible example, I'm sure you can do better
    public class GetAccountHandler : IQueryHandler<GetAccount, AccountDto>
    {
        public Task<AccountDto> HandleAsync(GetAccount query)
        {
            //put the handling code here
        }
    }
  2. Service/instance discovery. Totally agree. Gateway does not need to be concerned with load balancing. Maybe the microservice/instance registration sends the service name which matches the Consul service name?
  3. Auth is always tricky. That would be a definite concern. Maybe the microservice can indicate a policy name that is defined in Entrada when it registers it's capabilities.

Another one would be what happens if you are rolling out an update to your microservices which changes the capabilities? (adds an endpoint, handler, etc).

Like I wrote initially, not fully formed. :)

@spetz
Copy link
Member

spetz commented Oct 30, 2019

Yes, I think that services need to specify their endpoints and the request handling mechanism, so either by using attribute (like in your sample) or configuration via file (to make it a universal solution, not just for C# apps).

Service discovery - both the API and microservices need to beware of the common infrastructure, so whether it's Consul, orchestration engine with built-in DNS or something else, all of the requests have to be forwarded using the same mechanism and Gateway should only care about the service name.

Auth - as you said, either define a set of global claims in the Gateway/Identity Server or allow for arbitrary claims, as long as it works with the JWT.

Speaking of rolling updates, I think it would be possible to provide a special tag (besides the service name, something like version or so), that would be added both to Gateway and e.g. Consul, and based on the new version of given microservice, the load balancer could redirect the traffic properly (Fabio, Traefik or anything else).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants