I think layers are important (All internal data should be mapped onto DTOs to returned to a client IMHO) but it's also important to not have more than 2 layers to get to the core, ideally 1.
I've worked places before where they have you call through a function that calls a function that calls a function (replace "function" with "api endpoint" in some cases) because "Well we know function X works and so just call it", then fast-forward a year or two "Well we know function Y works, which calls X, so it's safest if you call Y, don't call X" and so on. This leads to a complete mess and tons of inefficiencies. Often "X" over/under-fetches what you want so you either have to throw away some of the result or add to it. I've even seen cases of Z->Y->X where X over-fetches, Y only uses a subset, and then Z has to re-fetch the data that Y threw away. All because someone decided an arbitrary layer is the new golden standard that everything should be built on.
I've worked places before where they have you call through a function that calls a function that calls a function (replace "function" with "api endpoint" in some cases) because "Well we know function X works and so just call it", then fast-forward a year or two "Well we know function Y works, which calls X, so it's safest if you call Y, don't call X" and so on. This leads to a complete mess and tons of inefficiencies. Often "X" over/under-fetches what you want so you either have to throw away some of the result or add to it. I've even seen cases of Z->Y->X where X over-fetches, Y only uses a subset, and then Z has to re-fetch the data that Y threw away. All because someone decided an arbitrary layer is the new golden standard that everything should be built on.