It depends how client friendly you want the API to be. I've recently seen an API that returns an object but in order to update a single field in the object the client has to call another endpoint to get extra information to add to the original object in order to PUT the updated one. I regard that as client unfriendly.
If a client GETs a Student and they get the full object Id, Name, Address, Street then I would expect PUT: /students/{id} to be able to handle a full object, updating fields that are different from the one in the database or wherever the object is stored. If the API gives the client a full object then the API should be client friendly and be able to accept a full object back rather than making the client deconstruct the object.
I wouldn't expect a client to have to extract an Address from the Student, then extract the Street from the Address and send that to PUT: /students/{id}/address/street if the API gave the client a full Student object in the first place.
The only downside to this approach is bandwidth. If a single letter in the Street changes the client has to PUT the entire Student object. So it really depends what the client is and what network it operates on. A REST client on the internet? Accept full objects. An embedded client on a resource constrained device? It may need to send fragments of the object but that leads to the REST endpoints matching the Student object hierarchy which to me is close coupling and not really recommended.