我有一个简单的场景,其中用户和技能之间存在关联, 意味着一个用户有很多技能,所以我尝试了:
@Data
@NoArgsConstructor
@Entity
@EqualsAndHashCode
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String name;
@OneToMany(mappedBy = "user")
private List<Skill> skills;
}
@Data
@NoArgsConstructor
@Entity
@EqualsAndHashCode
public class Skill {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String skillTitle;
@ManyToOne
@JoinColumn(name="user_id")
private User user;
}
@RepositoryRestResource(collectionResourceRel = "users", path = "users")
public interface UserRepository extends PagingAndSortingRepository<User, Long> {
List<User> findByName(@Param("name") String name);
}
@RepositoryRestResource(collectionResourceRel = "skills", path = "skills")
public interface SkillRepository extends CrudRepository<Skill, Long>{
}
通过以上所有内容,我都可以通过以下网址获得回复:网址http://localhost:8085/users/1
{
"name": "Root",
"_links": {
"self": {
"href": "http://localhost:8085/users/1"
},
"user": {
"href": "http://localhost:8085/users/1"
},
"skills": {
"href": "http://localhost:8085/users/1/skills"
}
}
}
不是问题,我没有弄清楚为什么不获取技能列表,为什么只获取技能列表
"skills": {
"href": "http://localhost:8085/users/1/skills"
}
不是与user/1
相关的技能的完整列表。
根据建议添加了投影: UserProjection.java
@Projection(name = "inlineData", types=User.class)
public interface UserProjection {
String getName();
List<Skill> getSkills();
}
UserRepository.java是
@RepositoryRestResource(collectionResourceRel = "users", path = "users", excerptProjection = UserProjection.class)
public interface UserRepository extends PagingAndSortingRepository<User, Long> {
List<User> findByName(@Param("name") String name);
}
响应为:
{
"name": "Root",
"_links": {
"self": {
"href": "http://localhost:8085/users/1"
},
"user": {
"href": "http://localhost:8085/users/1{?projection}",
"templated": true
},
"skills": {
"href": "http://localhost:8085/users/1/skills"
}
}
}
答案 0 :(得分:0)
响应正确,可以正常工作。 @RepositoryRestResource
遵循HATEOAS原则。 Spring documentation对此进行了如下解释:
5.1.3。资源可发现性
HATEOAS的核心原则是资源应该是可发现的 通过发布指向可用链接的链接 资源...
通过向根URL发出请求...客户端可以从中提取 返回的JSON对象,代表下一层的一组链接 可供客户端使用的资源...
您将获得代表资源的链接。要检索特定资源,您应该调用相应的URL。您对用户1的回答意味着,如果您想获得用户1的技能,则应致电URL“ http://localhost:8085/users/1/skills”。
如果您想象有一个显示用户1的属性的HTML页面,则更易于理解。该页面不直接显示技能,而是此页面包含指向技能页面的链接。仅当用户单击此链接时,“技能”页面才会加载。
对HATEOAS的理解非常重要。
当然,在某些情况下HATEOAS不是最佳选择。但是这里我们不是在讨论HATEOAS,而是在解释Spring的实现背后的想法。在许多情况下,这种方法确实很有帮助。当您拥有2个具有1-2个属性的实体时,您可以将这种方法视为过大杀伤力。但是,如果您有30-50个实体,每个实体具有3-5个关系,每个关系包含50-100个其他实体,则很难处理这样的数据模型。 HATEOAS可以使它变得更加容易。使用这种方法,您可以导航这些关系:加载一个实体,选择所需的关系,在此关系上加载实体,选择所需的实体,在该实体中选择所需的关系,加载该关系,或导航回通过父级关系等其父实体。