Is there a way to limit returned JSON depth in spring boot?

Viewed 628

I have a complex API with 10+ models and they have one-to-many relationships with each other.

organization hasMany program hasMany project hasMany etc

When I make a request GET /programs. I get a json response:

 "programs": [ "projects": [ "..." ] ]

This works good for a component that requires all the data on the tree. But I have a component that only requires programs and projects, so I want my json to be:

"programs": [ "projects" ]

Is there a way to pass a depth parameter from the client to spring boot and have it limit the json to specified depth.

I have seen jenkins do this with their api. You can say /api/json?depth=2 and it will limit the json returned.

2 Answers

One way to do it is to have a DTO classes and fill it manually based on depth. This way can be only for definitive depth:

Sample DTOs:

public class SampleDTO{

  ProgramDTO programs;

  ....
}

public class ProgramDTO{

  List<ProjectDTO> projects;

  ....
}

public class ProjectDTO{

  List<SomeOtherDTO> someOtherObjects;

}

And controller is like :


@GetMapping(path = "/api/json")
public SampleDTO getPrograms(@RequestParam("depth") Integer depth) {

   List<ProjectDTO> projects = // get Projects Logic;

  //if depth = 4 then set objects at depth 4 
  if(depth == 4) {
     //set objects at depth 4
  }

  //if depth = 3 then get someother data and add to projects 
  if(depth == 3) {
   List<SomeOtherDTO> someOtherObjects = //get logic;
   projects.setSomeOtherObjects(someOtherObjects);
  }

  return new SampleDTO(new ProgramDTO(projects) );
}

If you're using Jackson then @JsonIgnoreProperties might help you with this. This can be applied to classes and to properties.

Sample Code :

@JsonIgnoreProperties({ "id", "systemId" })
class Employee {
   public int id;
   public String systemId;
   public int empNo;
   public String name;

   Student(int id, int empNo, String systemId, String name){
      this.id = id;
      this.systemId = systemId;
      this.empNo = empNo;
      this.name = name;
   }
}

Output :

{
   "empNo" : 11,
   "name" : "Mark"
}

Note : If you don't want to ignore the properties, and the JSON response is too big, Then you will have to implement pagination.

Related