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 Club
with 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 fieldhref
to the Artist.– Jean Thomé