In practice it wouldn't make much sense to cache whole query responses to GraphQL queries because your hit rates would be too low due to the variability of the queries. You end up pushing a lot of the caching to the client. That's not really a big issue because if you're writing something like a Android or iOS app because you already need to be caching lots of data on the client-side to make the app responsive.
On the server you end up caching at lower levels in the stack. For example a query for user(id: 123456) {id, name} is going to need data from a key-value store containing user info. That access can easily be cached with something like memcache, saving load on the database. Cache-invalidation problems are also much easier to solve at these layers.