Excelente dica, apenas senti um pouco falta de alguma orientação de como deixar o json de resposta menos "prolixo". Ou como garantir objetividade do retorno da api com o mais necessário.

@hbm obrigado pelo feedback! Sobre o que comentou, acredito que a melhor forma de evitar isso é dividir sua API em entidades menores, evitar entidades que trazem listas de entidades filhas. Por exemplo: Post e Comentário, veja a abaixo.

Bom:

GET /posts [{"id":1,"title":"Meu title", "body":"texto do post"}]
GET /posts/1/comments [{"author":"ze ning", "text":"texto do comment"}...]

Ruim:

GET /postsAndComments {"title":"Meu title", "body":"texto do post", "comments": [{"author":"ze ning", "text":"texto do comment"}...]}

Uma dúvida, fazendo isso nos não aumentamos a quantidade de chamadas que o client para algum recurso?

Com certeza! Por isso é importante avaliar se o join que vc vai fazer pra trazer os recursos é mais onerante que fazer outra request. As vezes o join é mais onerante, então é interessante usar o poder computacional do frontend para juntar essas informações. Outro detalhe que quando vc ta trazendo payloads complexos (parent-childs) isso aumenta o tamanho de dados trafegados, o seu parse json demora mais e consequentemente mais esforço pro seu backend receber/enviar dados assim. Não existe uma receita de bolo falando que vc não pode fazer isso, tem casos que fazem sentido vc trazer retornos complexos, por exemplo: Telas de formulários onde diversas regras de negócio precisam ser ocultadas do frontend, retornos para gráficos... A questão aqui é saber decidir quando convém usá-lo.