Search code examples
javaspringentity

How to return specific part of object in JSON response


I try to build Spring Rest app. When I create class Activity and controller for return JSON data it always return a whole list of ActivityDetail but usually I want only one (the last item) or not all object data in response.

What should I do now? Create object ActivityWithOneDetail or ActivityWhitoutTitle? But how can I pass necessarily information into this objects without overflow database? I think that it doesn't make sense to get Activity object and create another object from that object (activity has repository public interface ActivityRepository extends JpaRepository { ... } so I have simple access to this object).

I see a lot of problem with keep relation in entity and object returns because sometimes I want return more, other times less data from controller but when I block pass data into JSON response in entity it affect all controllers. It's not elastic solutions so, I suppose you can give me another tips how can I return JSON objects from my controllers and keep good performance with Database (I suppose that getting all @oneToMany data from database is not what I should do in each request).

Below I paste some part of my code, but I think that this question is more theoretical.

@Entity
@Table(name = "ACTIVITY")
public class Activity {

    @Id
    @Column(name = "ID")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "CREATE_DATE")
    @Temporal(TemporalType.TIMESTAMP)
    @NotNull
    private Date createDate;

    @Column(name = "ACTIVE")
    @NotNull
    private Boolean active;

    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name = "ACTIVITY_USER", joinColumns = @JoinColumn(name = "ACTIVITY_ID", referencedColumnName = "ID"), inverseJoinColumns = @JoinColumn(name = "USER_ID", referencedColumnName = "ID"))
    @JsonBackReference
    private Set<User> users;

    @OneToMany(mappedBy = "activity_id")
    private List<ActivityDetail> activityDetails;

    @ManyToOne
    @JoinColumn(name = "ACTIVITY_OWNER")
    private User activityOwner;

    @OneToMany(mappedBy = "activityParent")
    @JsonBackReference
    private List<Task> activityTasks;
} 
// Constructor, Getter, Setter

And part of my constructor hire:

 @RequestMapping(value = "/api/{userId}/activities", method = RequestMethod.GET)
    public List<Activity> activities(HttpServletRequest request, @PathVariable(value="userId") final Long id){
        User user = userRepository.findById(id);

        List<Activity> activities = activityRepository.findAllByUsers(user);

        return activities;
    }

Solution

  • There is few possible approaches :

    1) Try to use Spring Data Rest and their Projections feature. Here is more description

    2) Or, if you need some absolutely flexible then try this approach. GraphQL is an approach to build REST API where client specify data that should be retrieved.

    P.S. You always can create DTO objects from your entities. Yes, it will require more classes and memory in runtime but no issues with database.