It's generally bad practice to add fields to a type that will only be populated in a specific context. You could add a rating to the Book type, but then you would only resolve it with a value when fetching a list of books that have been borrowed -- if you're fetching a book or an array of books for some other field, a rating field may not necessarily make sense.
What you probably want is another type (and another table, if we're talking about the underlying database) to join the user with their borrowed books. Something like:
type User { id: ID! checkouts: [Checkout] } type Book { id: ID! name: String checkouts: [Checkout] } type Checkout { user: User book: Book rating: Int lastCheckoutDate: Date # other fields specific to the checkout itself }
This makes the resulting data returned by a query a bit more nested, but it also makes the data easier to model and reason about. The resolvers for these fields can then also be relatively straightforward -- the checkouts field for User and Book just gets all Checkouts by User or Book id. The user and book fields on Checkout just query the User or Book by id.