Circular dependency on Rest API with Spring Boot

Asked

Viewed 914 times

3

I’m venturing into developing a Rest API using Spring Boot, JPA with Hibernate and Maven to manage the repositories. In my modeling I have a class Club:

@Entity
@Table( name = "CLUB")
public class Club {

   /**
    * Id da entidade
    */
   @Id
   @GeneratedValue(strategy = GenerationType.AUTO)
   private Long id;

    /**
    * Atual técnico do clube.
    */
   @OneToOne(mappedBy = "actualClub")
   private Coach coach;
   
   //Outros atributos, getters e setters
  }

who has a relationship @OneToOne with class Coach:

@Entity
@Table(name = "COACH")
public class Coach extends Person {

   /**
    * Clube atual do técnico.
    */
   @OneToOne
   @JoinColumn(name = "CLUB_ID")
   private Club actualClub;

   //Outros atributos, getters e setters
   
}

The Class Person has some additional attributes, among them the id, which follows the same logic implemented in Club.

Finally, I also have the class ClubController to handle some requests:

@RestController
public class ClubController {

   /**
    * Instância da classe de serviços da entidade <i>Club</i>
    */
   @Autowired
   private ClubService clubService;

   /**
    * Retorna JSON que representa o clube com o 'id' especificado.
    *
    * @param id Identificador do clube a ser buscado.
    * @return ResponseEntity Objeto com detalhes da requisição HTTP, como o Status.
    */
   @RequestMapping(value = "/clubs/{id}", produces = MediaType.APPLICATION_JSON_VALUE,
           method = RequestMethod.GET)
   public ResponseEntity<?> getClubById(@PathVariable Long id) {

      final Club club = this.clubService.findById(id);
      if (club != null) {
         return new ResponseEntity<>(club, HttpStatus.FOUND);
      } else {
         return new ResponseEntity<>("Não encontrado", HttpStatus.NOT_FOUND);
      }
   }
   
   /*Entre outros métodos...*/
   
}

The problem I’m having is that the returned JSON has a circular relationship between Club and Coach. That is, I receive the data of the club, among them the data of the technician. Within the attributes of the technician there is again the data of the club and so continues... x(

And that’s certainly gonna happen when I go relate Clubwith Player further on.

One solution I found was this: Link. Who uses @JsonIdentityInfo in class declaration. A problem I noticed in this solution is the overhead of information that is not always needed. For example, when it is @OneToMany with Player, I would necessarily bring all the players' information when searching for a club.

Researching a little more, I found another possible solution (not yet tested) from Sring himself: Spring Hateoas. That way I could add links (href) to certain attributes, and I would only request for more information if it was really necessary. But I also saw that HATEOAS still has some limitations.

So my question is: what would be the best approach to these cases? Is there any other option?

My idea later is to consume this API in an iOS app. (This may be important to help answer)

  • Detail 1: if the option with @JsonIdentityInfo If chosen, I would have to use UUID for the JPA @Id fields, as detailed in the Link. Detail 2: The Spotify API uses a HATEOAS-like approach link, looking for a track, there is a field href to the Artist.

1 answer

1

I treat this reference as follows.

On the association side I want json to be generated I note the attribute with @JsonManagedReference, and on the other side I note with @JsonBackReference.

If in the serialization of the object is found the @JsonBackReference, in this object this attribute will not be serialized because the other side carries this responsibility,

Browser other questions tagged

You are not signed in. Login or sign up in order to post.