Christopher
Christopher

Reputation: 1645

Entity relationships in POSTed JSON with Spring Boot

Spring Boot (using Jackson) handles object mapping quite well between a JSON document and a Java POJO. For example:

{ id: 5, name: "Christopher" }

can be accepted by:

@PostMapping("/students/{id}")
public Student Update(Long studentId, @RequestBody Student student) {

    studentRepository.save(student);

    return student;
}

and will be correctly mapped into:

public class Student {
    private Long id;
    private String name;
    ...
}

But what about nested models in the JSON?

{ id: 5, name: "Christopher", grades: [ {id: 1, letter: 'A'} ] }

Or optional models in the JSON?

{ id: 5, name: "Christopher" }
(Purposefully leaving out 'grades', though it could be accepted.)

Or indicating the removal of an association in JSON (example using Rails' _destroy flag)?

{ id: 5, name: "Christopher", grades: [ {id: 1, letter: 'A', _destroy: true} ] }

Or creating an association by leaving out the ID?

{ id: 5, name: "Christopher", grades: [ {letter: 'A-'} ] }

Does Spring Boot support these ideas?

Upvotes: 2

Views: 2165

Answers (1)

Simon Ludwig
Simon Ludwig

Reputation: 1814

But what about nested models in the JSON?

Nested Models are mapped as you maybe would expect, assume you have the following model:

public class Product {
    private String name;
    private List<Price> prices;
}


public class ProductPrice {
     Long idPrice;
     Integer amountInCents;
}

Jackson would create the following JSON from this Schema:

{
    "name":"Samsung Galaxy S7",
    "prices":[
         {
              "idPrice":0,
              "amountInCents": 100
         }
    ]
}

Or optional models in the JSON?

You can annote field with @JsonIgnore. If you, for example, annotate the prices with @JsonIgnore, no prices will be serialized from jackson.

Or indicating the removal of an association in JSON (example using Rails' _destroy flag)?

I would create an additional mapping to delete a associations. This has another advantage, the API is self explaining..

 @DeleteMapping("/students/{id}/grade/{idGrade}")
 public Student Update(Long studentId, @PathVariable Long idGrade) {

     studentService.deleteGrade(studentId,idGrade);

     return student;
}

Or creating an association by leaving out the ID?

I would here also create an additional Mapping:

@PostMapping("/students/{id}/grade")
public Student Update(Long studentId, @PathVariable String grade) {

     studentService.addGrade(studentId,grade);

     return student;
}

Note: I do not use repositories directly, I create a service layer and every repository has package protected access. In the service layer you create methods like addGrade, deleteGrad, addStudent, deleteStudent and so on

Upvotes: 1

Related Questions