Overfetching when only requesting id

I have a performance problem where overfetching is responsible for a huge portion of the load times.

I often find places where I only need the id of objects in a list and write queries like below:

// Queries on client
const GET_USER = gql`
  query GetUser {
    getUser {
      id
      friends {
        id
      }
    }
  }
`;
const GET_FRIEND = gql`
  query GetFriend($id: ID!) {
    getFriend(id: $id) {
      id: ID!
      (...lots of stuff)
    }
  }
`;

However this results in a lot of overfetching as the Friend.id already is available in parent (that is in FriendModel.friends) but the Friend resolver isn’t aware that id is the only field being requested.

I realize that I could manually write resolvers for all the fields in Friend where all other fields except id fetch the friend from the dataSource, but that would be horrible to read and maintain.

Ofcourse this is just a example attempting to show the problem, in reality the models, graph and queries are much more complex.

Is there a good way to prevent the unnecessary fetching for the GetUser query?

// Mongoose (MongoDB models)
const FriendModel = mongoose.model('Friend', mongoose.Schema({
  (...lots of stuff)
});
const UserModel = mongoose.model('User', mongoose.Schema({
  friends: [{
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Friend',
  }],
});

// Server GraphQL
export const typeDefs = `
  type Friend {
    id: ID!
    (...lots of stuff)
  }
  type User {
    id: ID!
    friends: [Friend]!
  }
  type Query {
    getUser: User
    getFriend(id: ID!): Friend
  }
`;
const resolvers = {
  User: {
    friends: async (parent, args, context, info) => {
      return context.dataSources.friends.getMany(parent.friends);
    },
  },
  Query: {
    getUser: async (parent, args, context, info) => {
      return context.getUser();
    }
    getFriend: async (parent, args, context, info) => {
      return context.dataSources.friends.get(args.id);
    }
  }
}