Finding the Right Shard

We chose shopId to keep each shop’s documents together. The router still needs to know which shard holds a given shop. For Shopend, we use a directory. The directory is a table that records which shard holds each shop:

Shop Shard
mugshop A
wickandwax A
threadline B

Following a request

Suppose a shopper opens product 42 in the mug shop. The storefront sends its request to /shops/mugshop/graphql, so the Shopend API instance knows the shop is mugshop. The router looks up that shop in the directory, finds shard A, and sends the database operation there:

sequenceDiagram
    participant A as Shopend API Instance
    participant R as Shard Router
    participant D as Directory
    participant S as Shard A
    A->>R: Find product 42 in mugshop
    R->>D: Where is mugshop?
    D-->>R: Shard A
    R->>S: Find product 42 in mugshop
    S-->>R: Product
    R-->>A: Product

The storefront only puts the shop in the URL. It does not need to know which shard holds the shop’s data, because the router looks that up in the directory.

Maintaining the directory

The directory lets us choose where to place each shop. If we add shard C, none of the existing entries change. We can assign new shops to C or move some existing shops there.

To move a shop, we have to move its data and also update its entry in the directory.

In practice, there is more than one router. If the routing logic is in the data access layer, every API instance has its own. Asking the directory for every database operation would add a request to each one, so each router keeps a copy of the directory entries it has looked up.