How would you weigh a convention-derived route table against an explicit central route configuration for a large, multi-team application?
answer
- two models, two different readers
- locality of change versus readability of the whole
- authored routes versus routes from data
- hybrid: convention plus a generated listing
- migration cost is links, not routes
basics
~20 sDecide by who reads the route table and how routes are created. Convention removes registration bugs and scales across teams; a central list stays readable and programmable. At scale, usually convention plus a generated listing and enforced conventions.
solid answer
~50 sThese optimise for different readers. A **convention-derived table** optimises the author: a route exists because a file exists, there is nothing to register and nothing to merge, which is why it scales across teams working in parallel. A **central configuration** optimises the reader and the machine: the whole URL space is in one file, routes can be composed programmatically, and precedence is explicit. The costs mirror that — convention gives up a readable table and makes renames invisible to tools; a central list becomes a contended file, drifts from the code it points at, and can carry a route that nothing implements. For a large multi-team application I take convention as the base and buy back what it spends: a **generated, committed route listing**, directory-level ownership, typed route helpers so renames fail at compile time, and a build-time conflict check. I go central only where routes are generated from data.
go deeper
Recall the basic contrast: one model derives URLs from where files sit, the other lists them in one place. Each makes a different task easy — creating a route, or reading them all.
Explain the concrete mechanics behind the tradeoff: merge behaviour, precedence, drift between a listed route and its implementation, and how each model handles a rename.
Show how you compensate in practice — a generated listing, ownership on directories, typed path helpers, conflict checks — and when routes generated from data break the convention model.
Decide with evidence from your own repository, state who the route table's readers are, record the reason rather than the verdict, and price a future migration in links and redirects rather than in routes.
## What each model actually optimises The choice is usually argued as taste. It is better argued as **who the route table is for**. | Dimension | Convention-derived from the tree | Explicit central configuration | |---|---|---| | Adding a route | create a file; nothing to register | edit a shared file; a merge point | | Reading the table | walk a directory, or read a generated listing | open one file | | Precedence | structural, by specificity | explicit, often by order | | Programmatic routes | awkward — the tree is authored | natural — it is data | | Rename safety | invisible to tools unless types are generated | a referenced entry a tool can follow | | Parallel work | high — teams touch disjoint directories | contended — one hot file | | Drift | impossible: the files *are* the table | possible: an entry with no implementation | Neither column is a winner. Convention trades **readability of the whole** for **locality of the change**; central configuration trades the reverse. ## How scale changes the weighting For a small application the difference barely registers: one person can hold thirty URLs in their head either way. Three things shift the balance as an application grows. 1. **Number of concurrent authors.** A single route file is a merge-conflict magnet and, worse, a review bottleneck — every route change touches a file half the organisation watches. Directories partition cleanly, and ownership rules can follow them. 2. **Number of readers who are not authors.** Support, security review, SEO and analytics all want the question "what URLs exist?" answered in seconds. A directory tree answers it badly, and this is the cost most teams underestimate. 3. **Where routes come from.** Authored routes suit a tree. Routes derived from data — a catalogue, a content source, a tenant list — are not files, and forcing them into a tree means a variable segment plus a build-time list of values, which is a different mechanism with its own operational story. ## The hybrid I would actually run I would not treat this as either-or. Take convention as the base, then spend deliberately to buy back what it costs: - **A generated route listing, committed to the repository.** It is the artefact non-authors read, and its diff makes every URL added, renamed or removed visible in review. - **Ownership on directories.** Review routing and code ownership follow the tree, which is the one thing the tree is genuinely good at. - **Generated route types and a path-building helper**, so a rename fails at compile time instead of on a click, with a lint rule keeping raw path literals out. - **Conflict and convention checks in the pipeline** — duplicate URLs, ambiguous equally-specific siblings, and a cap on how deep organisational grouping may nest before the URL-to-file mapping stops being guessable. - **A written rule for data-driven routes**: which variable segments exist, where their value lists come from, and who owns the refresh when the data changes. ## What would make me choose differently - **Routes are mostly generated from data, not authored.** Then the table is data already, and expressing it as configuration is honest rather than clever. - **The URL space is a published contract with outside consumers.** A single reviewable file that changes only deliberately is worth more than authoring convenience. - **The framework's conventions do not fit the URL shape** — heavy grouping, many exceptions, routes that must be composed at runtime. Fighting a convention with special cases is worse than not using it. - **The team is small and the route count is low.** Then pick whichever the framework makes default and spend the attention elsewhere; this decision does not pay off at that size. ## How to make the decision defensible Write down the three questions that actually decide it — who reads the table, how routes are created, how often they change — answer them with numbers from your own repository, and record the answer as a decision with its reasons. The reason matters more than the verdict, because the verdict will be revisited: the migration cost between models is not in the routes themselves but in **every link, redirect, test and external reference** that grew around them, and a team that knows why the current model was chosen can tell whether the reason still holds.
- Which cost of convention do teams most often underestimate?That no one can read the route table. Authors never feel it because they work one directory at a time, while support, security, SEO and analytics need the whole URL space at once. A generated, committed listing is the cheapest way to pay that back.
- Why are data-driven routes the strongest argument for explicit configuration?Because the route set is not authored, so there are no files to create. In a tree it becomes a variable segment plus a build-time list of values that has to be refreshed and owned; as configuration it is just data, which is what it already was.
- What makes migrating between the two models expensive?Not the routes — the surroundings. Links, redirects, tests, documentation, analytics definitions and external references all encode the URL space, and any change that disturbs the paths has to account for consumers you cannot redeploy. Migrating while keeping URLs identical is far cheaper than reshaping them at the same time.
saying these in an interview costs you the question
- Argues one model is simply better without naming a reader
- Ignores that a single route file is a merge and review bottleneck
- Assumes a convention-derived table needs no readable artefact
- Forgets routes generated from data have no files to create
- Prices a migration as route edits, not as link and redirect churn
- Treats heavy grouping as free rather than as lost legibility