Separation of concerns
Organizing schemas by features and teams
Apollo Federation introduces an important new principle to modular schema design: proper separation by concern. It's the key architectural quality that allows separate teams to collaborate on a single product-centric graph without stepping on each other's toes.
When you start thinking about how to break up a monolithic schema into modular parts, it can be tempting to divide things up by type. For example, you could make one module responsible for the
User type, another one for your
Product type, and a third one for the
This may seem to make sense at first, but it quickly breaks down. The problem is that features or concerns usually span types. For example, suppose we want to add a new
topNegativeReviews field to the
Product type in the above schema. Even though it lives on the
Product type, this addition is almost certainly the responsibility of the team responsible for reviews. This isn't just a conceptual point about team structure: the product service won't know how to resolve a query for
topNegativeReviews, because data about reviews is stored in the reviews system (as a reviews table with foreign key references to products, for example).
Another way to think about the same problem is to consider an important type like
Product. Often, no single team controls every aspect of such types, and it becomes quite awkward to colocate the definitions of each field on such types.
So instead, Apollo Federation allows you to extend an existing type with additional fields, using GraphQL's
extend type functionality. That means we can break up a schema across boundaries that correspond to features or team structure. For example, a team working on a new reviews feature could develop their changes in one place, combining new types like
Review with extensions to existing types, like adding the ability to navigate from a
Product to the associated reviews:
The result is the best of both worlds: an implementation that keeps all the code for a given feature in a single service and separated from unrelated concerns, and a product-centric schema with rich types that reflects the natural way an application developer would want to consume the graph.