Some mix of politics, management, and prioritization, in practice, when I've seen it. (It's often hard to fully separate those three things.)
Consider an app that has a TV interface, a desktop interface, and a phone interface. The UI might be very different on each. You might want different art at different sizes/aspect ratios for different interfaces (consider different ways of browsing content on a streaming media service, including potentially "live TV guide" views and/or series-vs-show-level navigation). You might iterate on those interfaces at different rates - it's easier to release to the web than to mobile, and it's a LOT easier to release there than to, say, Samsung TVs.
So either distinct sets of APIs for each, or some sort of graphql-style "get just what you ask for" open-ended API contract becomes necessary.
The former is often easier to optimize for performance if you don't truly need unlimited permutations, but just a handful of them.
Nothing here is impossible to do out of a single API gateway, but you're likely run into some problems over time:
* at a certain number of people, a single team working in a single codebase often steps on each other's feet more than is productive
* at a certain feature complexity, the API gateway becomes much more "custom logic for each device" than "shared aggregation of stuff from individual backends"
* at a certain company/product organization/roadmap size, trying to sequence and deliver priorities for three competing client teams at the same time becomes tricky
Splitting up the teams to each focus on different clients lets you accomplish organizational resource splitting at a higher level (how much do we staff these teams) than stakeholders having to jockey for prioritization on every single feature.
Once the teams are split up, splitting up the codebases and deployables makes sense too - if you're responsible for the mobile API, you don't want to be paged because the TV team pushed something that screwed up your crap, etc. You can do finer-grained optimizations at that point, too.
Consider an app that has a TV interface, a desktop interface, and a phone interface. The UI might be very different on each. You might want different art at different sizes/aspect ratios for different interfaces (consider different ways of browsing content on a streaming media service, including potentially "live TV guide" views and/or series-vs-show-level navigation). You might iterate on those interfaces at different rates - it's easier to release to the web than to mobile, and it's a LOT easier to release there than to, say, Samsung TVs.
So either distinct sets of APIs for each, or some sort of graphql-style "get just what you ask for" open-ended API contract becomes necessary.
The former is often easier to optimize for performance if you don't truly need unlimited permutations, but just a handful of them.
Nothing here is impossible to do out of a single API gateway, but you're likely run into some problems over time:
* at a certain number of people, a single team working in a single codebase often steps on each other's feet more than is productive
* at a certain feature complexity, the API gateway becomes much more "custom logic for each device" than "shared aggregation of stuff from individual backends"
* at a certain company/product organization/roadmap size, trying to sequence and deliver priorities for three competing client teams at the same time becomes tricky
Splitting up the teams to each focus on different clients lets you accomplish organizational resource splitting at a higher level (how much do we staff these teams) than stakeholders having to jockey for prioritization on every single feature.
Once the teams are split up, splitting up the codebases and deployables makes sense too - if you're responsible for the mobile API, you don't want to be paged because the TV team pushed something that screwed up your crap, etc. You can do finer-grained optimizations at that point, too.