Usually sharding logic are placed in appserver. Query will be passed to the specific shard by querying the meta. Apart from appserver, where else sharding logic can be placed so that load in appserver can be reduced.
A fairly popular solution is to use the Ambassador pattern.
It is understood that an additional application will be launched next to the main one. Shard distribution logic will be placed in the ambassador. Thus, the main service will be unloaded.
With this approach, the distribution service and unnecessary load are removed from the main service.
It is worth noting that it is important to place the ambassador in one physical host to reduce network latency.
This may not be the best approach, but just one option.