【发布时间】:2019-04-26 13:13:00
【问题描述】:
我不知道如何正确设计电影数据库 Web 应用后端的架构。
我有一个电影实体,它有一个流派实体列表和一个演员实体地图以及他们在电影中的角色:
// ...
@Data
@Entity
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class Movie {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
private String director;
private Date releaseDate;
private Long posterId;
@ManyToMany
@JoinTable(
name = "MOVIE_GENRES",
joinColumns = @JoinColumn(name = "MOVIE_ID"),
inverseJoinColumns = @JoinColumn(name = "GENRE_ID"))
private Set<Genre> genres = new HashSet<>();
// TODO how to rename value column (CAST -> ACTOR_ID)
@OneToMany
@MapKeyColumn(name = "ACTOR_ROLE")
private Map<String, Actor> cast = new HashMap<>();
// ...
}
我还有一个用于电影的 REST 控制器:
@RestController
public class MovieController {
private MovieRepository repository;
public MovieController(MovieRepository repository) {
this.repository = repository;
}
@GetMapping("/api/movies")
public List<Movie> all() {
return repository.findAll();
}
@PostMapping("/api/movies")
Movie newMovie(@RequestBody Movie newMovie) {
return repository.save(newMovie);
}
@GetMapping("/api/movies/{id}")
Movie one(@PathVariable Long id) {
return repository.findById(id)
.orElseThrow(() -> new MovieNotFoundException(id));
}
@PutMapping("/api/movies/{id}")
Movie replaceMovie(@RequestBody Movie newMovie, @PathVariable Long id) {
return repository.findById(id)
.map(movie -> {
movie.setTitle(newMovie.getTitle());
movie.setDirector(newMovie.getDirector());
movie.setReleaseDate(newMovie.getReleaseDate());
movie.setGenres(newMovie.getGenres());
movie.setCast(newMovie.getCast());
return repository.save(movie);
})
.orElseGet(() -> {
newMovie.setId(id);
return repository.save(newMovie);
});
}
@DeleteMapping("/api/movies/{id}")
void deleteMovie(@PathVariable Long id) {
repository.deleteById(id);
}
}
这就是我打电话给/api/movies 时的样子。我也收到每部电影的所有类型和演员信息。这个可以吗?在获取所有电影的列表时,我什至不需要所有这些信息。
如果我遵循 REST 原则,我不应该通过/api/movies/{id}/cast 获得演员表吗?我知道如何添加另一个只返回演员表的@RestMapping,但它不会改变演员表仍将包含在每个/api/movies 调用中的事实。
{
"id": 1,
"title": "The Matrix",
"director": null,
"releaseDate": null,
"posterId": 1,
"genres": [
{
"id": 4,
"name": "Science Fiction"
},
{
"id": 1,
"name": "Action"
}
],
"cast": {
"Agent Smith": {
"id": 3,
"name": "Hugo Weaving",
"gender": "MALE",
"dateOfBirth": "1960-04-04"
},
"Morpheus": {
"id": 2,
"name": "Laurence Fishburne",
"gender": "MALE",
"dateOfBirth": "1961-07-30"
},
"Thomas A. Anderson / Neo": {
"id": 1,
"name": "Keanu Reeves",
"gender": "MALE",
"dateOfBirth": "1964-09-02"
}
}
}
【问题讨论】: