I personally like the approach using DTOs, because it gives much needed flexibility, for example having different DTO classes for create, update and read endpoints, or have multiple DTOs for different types of consumers (maybe some internal properties should not be ‘leaked’ to external users). I usually have my entities extend an interface to ensure they implement a toDTO() method, and the DTOs have an interface to ensure they implement toEntity(). Finally, it allows you to change the table/entity classes without changing the API of your service directly, which could also have benefits down the line.