If that's too much work, then an easy preliminary step is to add the abstraction layer in your application code. That gets you most of the benefits of a proxy for the purpose of having clean application logic, and makes it easy to switch over later, but is less powerful and feature complete.
If you use Citus, you don't have to make any changes in your application. You just need to remodel your data and define your tables' sharding column(s). Citus will take care of the rest. [1]
In other words, your app thinks it's talking to Postgres. Behind the covers, Citus shards the tables, routes and parallelizes queries. Citus also provides transactions, joins, and foreign keys in a distributed environment.
[1] Almost. Over the past two years, we've been adding features to make app integration seamless. With our upcoming release, we'll get there: https://github.com/citusdata/citus/issues/595
If I understood your example query, your application serves vendors and each vendor has different products. Is that correct?
You can approach this sharding question in one of two ways.
1. Merge different product tables into one large product table and add a vendor column
2. Model product tables as "reference tables". This will replicate the product tables to all nodes in the cluster
Without knowing more about your application / table schemas, I'd recommend the first approach. I'd also be happy to chat more if you drop us a line.
For me a major question I have as I consider sharding is what my application code will look like. Let's say I have a query like:
'select products.name from vendor inner join products on vendor.id = products.vendor where vendor.location = "USA"'
If I shard such that there are many products table (1 per vendor), what would my query look like?