Strongly Schema'd interfaces makes client development go faster and smoother in general.
What trade-offs exist for strongly typed schemas? It reminds me of indexing database inserts, longer to write and faster to subsequently query. I would argue strong schemas require more design and architectural discipline during constructions and are thus easier to consume down the line.
To quote Bay Area rapper G-eazy "everything costs something bro"
When people speak of tooling they are almost certainly talking about Apollo. I think you could probably find a similar analog in the SOAP XML days. There were lots of vendors, lots of tooling, and mostly the same challenges and outcomes. It could be as nice as you wanted if you spent the time and effort getting there.
To make this more concrete, GraphQL is "strongly typed" in the sense that you get a run-time error when you use the types incorrectly. That's fine for development. Not so much for production. In order to get end-to-end typing you need to integrate with TypeScript or whatever language you're using. That has its own set of challenges. Your build process needs to know which GraphQL endpoint to use (not so easy when doing development on the API or need to use staging environments, etc.) and then generate typings based on that.
Errors are another GraphQL travesty. Do you use out-of-band HTTP errors? In-band error codes? Both? (ugh, but probably once more than 1 developer touches the code). Do those errors kill your entire query? What or who determines that?
I could also mention caching. But that's enough headaches for today. You need tooling just to get up to bog standard HTTP and browser caching gives you for free.
If unions are used for errors as well, you essentially have the Result/Either type inside GraphQL at compile time. This is much stronger than anything REST provides.
Hasura https://hasura.io/
Examples of "batteries included" GraphQL. Combine with a type generator for the language of your choice (eg. https://the-guild.dev/graphql/codegen), and you've got your client interface to avoid any type errors. Each comes with a GraphiQL UI for access out of the box as well. It's more turnkey than any REST solutions I've seen, that's for sure.
For different environments, it's quite possible (even normal?) to generate your types and GraphQL schema ahead of time, before CI/CD build of the UI to catch errors early at compile time.
Now add in SvelteKit with KitQL (https://www.kitql.dev/), and you've got a very simple, flexible, and efficient end-to-end solution.
As for errors, because each resolver can generate errors and not all errors are considered fatal, the errors must necessarily be embedded with the response and treated by the network client as they see fit. It's definitely different from REST, but not inferior. It's a different set of tradeoffs. When using a schema generator like Postgraphile or Hasura, it's unlikely you'd get errors in practice. The endpoints are basically guaranteed to resolve, and the generated SQL is nigh certain to execute correctly. If you get one error, chances are the whole endpoint is down due to a database connectivity problem. (That has been my experience at any rate.)
Don't take my word for it. Bring up a Postgres database, put some data in, and point one of these tools at it. I think you'll be pleasantly surprised. You may still prefer REST (or gRPC), but I think we can both agree that "batteries included" is definitely an option with GraphQL.
...
Organizationally speaking, I've worked in a company that an interesting approach to federated teams: All the backend applications would have an GraphQL endpoint that would connect to a middleware where all front-end would consume the data.
This allowed not only to avoid that over fetching, but different applications with different data needs could cross fetch the data via GraphQL and resolve them and display it in their own front-end.
Took a lot of work to reach a level of maturity but was the best place that I've worked in terms of federated services/backends serving multiple front-ends.