0

Background: I'm splitting a monolithic multi-tenant chat bot builder application. Each customer registers an API token for a third party API which their bot will run on such as slack/telegram/discord. They then use our service to code the "brains" behind the bots functionality.

I have identified a number of microservices such as command builders, announcement builders etc as their development cycle varies and deploying all in one go causes a lot of headaches.

Within the monolith and whilst they use a single db, the calls to the third parties is easy as the API keys are stored in a table beside the bot's profiles (username, id's etc). The existing code over the years looks to be peppered with direct calls to the APIs picking up keys from the DB as needed.

Question: I'm wondering how to handle the interactions with those third party APIs, including the storage of their keys now that I have separate services which also need to be multi-tenant aware.

I have considered creating a dedicated "notifications" style service which looks after keys and routing to correct third parties or whether sticking to isolation I duplicate key information across each service that can independently call directly as needed.Some need to be making calls based on events received from webhooks, some just sit back and run on a scheduler calling the third party API at set times.

The only reason for considering the latter is simplicity in direct calls and ownership, but there is the trade off for keeping the keys up to date (but they will very rarely change) and the risk of rate limiting if not centralised.

2 Answers 2

1

Unless I'm missing something, it sounds like you could feasibly keep all the keys in the existing database and have the separate microservices query it as needed. There's no rule that says a microservice has to have its own datastore. If you wanted you could also implement caching in each service to limit queries (if the same keys are queried often and the DB becomes a bottleneck).

But it sounds like you are just wanting to split them for ease of development and independent deployability. The trade-off here is slightly more complexity if the database schema needs to change. you'll need to co-ordinate that change across the services that are affected by it. If the schema rarely changes (at least the common parts) then this might not be a problem.

Maybe also consider putting a proxy in front of the database server to manage the connection pool. This means the services can scale independently of each other and don't need to worry about starving other services of DB connections.

1

Have you considered including an API proxy as one of the microservices which would handle the third-party authentication stuff and could additionally do caching and bookkeeping?

That way, only this proxy microservice needs to know the actual credentials and how they should be presented to the external API, making it easier to harden against credential leakage. Other microservices would call it with just a simple token identifying the tenant. This might simplify the other microservices, too, as they would not need to handle caching in each of them.

As http caching semantics are relatively well defined, you could run several instances of these for increased availability, avoiding a single point of failure. You would need to decide whether they share one database or keep local copies, which is a trade-off between ease of deployment and better performance/resilience.

Of course, this approach adds a small additional latency, which shouldn't be much of a problem with the kind of services that you mention.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.