Reusing the same Domain Object in For Get and POST

1.3k views Asked by At

Assuming I have a student Object

public class Student{
private long id;
private string name;
private List<string> courses
}

In a typical Get request, to get a student I send the Student object to the client.

In the case of a PUT request to modify the Student object by adding or removing a course or a POST request to create a Student record, I only need to receive from the client the student.id and the list of courses.

My question is, Can I send back the same Student object from the client in the PUT or POST request without including the name or maybe have name=null? Or should I create a separate domain object that will be sent by the client for example:

    public class StudentReponse
{
       private long id;
       private List<string> courses;
}

I guess my generic question is, should we separate the Request and response objects in Rest API? or for code re usability try to use the same domain objects for both directions?

1

There are 1 answers

2
hovanessyan On

should we separate the Request and response objects in Rest API?

Yes - it allows to evolve both the request and response independently. If you follow REST practices when a create is issued, you should return 201 - created and the ID of the newly created object.

If the client requires details about it, the client can use the ID + GET to get the full resource representation.

Also consider not exposing the domain objects directly through REST. For example having a domain entity object - it will probably have some fields related to persistence layer like database Id, createdOn, createdBy - etc. Those fields should not be sent to the client. Use a simple StudentDto (StudentResponse, StudentResponseDto whatever you want to call it) representation, which holds only those fields, which are of interest to the client.

Keeping domain and response objects separate also gives you the ability to evolve them separately or change the data representation. Imagine you have a JPA Entity and you use both JPA and Jackson annotations in the same class - it's very messy and hard to read and maintain.

Update:

If you're using the same object to be modified by the client and sent back to the server, I guess you could reuse it and model it like this:

get

@GetMapping("/students/{id}")
public StudentDto getStudent(@PathVariable long id) {
    return studentService.get(id);
}

update (replace)

@PutMapping("/students/{id}/")
public ResponseEntity updateStudent(@PathVariable long id, @RequestBody StudentDto student) {
    return new ResponseEntity(studentService.replaceStudent(id, student), HttpStatus.OK);
}

OR

update (partial update)

@PostMapping("/students/{id}/")
public ResponseEntity updateStudent(@PathVariable long id, @RequestBody StudentDto student) {
    return new ResponseEntity(studentService.updateStudent(id, student), HttpStatus.OK);
}