我已经开始实现一个Web前端来操纵Spring Data Rest
服务于传统关系数据库的RESTful服务。这是通过AngularJS
完成的,我发现的angular-hal
库非常符合HATEOAS
的{{1}}哲学和形式主义。
例如,我只需要知道第一个API端点('/'),然后我的所有查询都是通过关系完成的,而不需要关心网址。 我遇到的问题是能够直接访问显示我的某个实体的页面。
我们以联系人存储库为例。如果我从主页开始,然后浏览联系人列表,然后选择我想要详细查看的联系人,没有问题。
但我无法直接访问显示联系人详细信息的页面:资源从列表控制器注入编辑控制器,编辑控制器无法知道请求的URL,如果没有告知列表控制器。
根本问题是,对于Spring Data Rest
,实体没有Spring Data Rest
的公共字段(不在JSON中),并且存储库没有API id
来按ID搜索。< / p>
我想过一些解决方案,但我不喜欢它们中的任何一种。
1。在后端解决
relation
方法Projection
添加到需要加入书签的所有实体getId()
2。使用自我关系
findById()
angular-hal
方法$href('self')
来解析资源第3。忘记HATEOAS
halClient.$get(resourceUri)
,只使用普通旧网址映射angular-hal
那么,我错过了什么吗?在完整的RESTFul HATEOAS环境中访问数据的最佳实践是什么?
答案 0 :(得分:1)
我找到了exposeIdsFor
方法,可以在JSON中添加用@Id注释的字段。
@Configuration
public class RepositoryConfiguration extends SpringBootRepositoryRestMvcConfiguration {
/**
* add here the main resources that would need direct access from outside
*/
@Override
protected void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
config.exposeIdsFor(Contact.class, User.class);
}
}
然后我将我想要公开的所有实体从公共抽象类
继承@MappedSuperclass
public abstract class AbstractEntity {
@Id @GeneratedValue
Long id;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
此抽象类由@NoRepositoryBean
存储库
@NoRepositoryBean
public interface AbstractEntityRepository<T extends AbstractEntity> extends JpaRepository<T, Long> {
@RestResource(rel = "byId")
T findById(@Param("id") Long id);
}
然后我可以为我关心的实体公开id和方法byId():
@Entity
public class Contact extends AbstractEntity {
@Column
String name;
@Column
String email;
}
public interface ContactRepository extends AbstractEntityRepository<Contact> {
}
我认为这可以很好地解决问题并允许以较低的价格直接从客户端访问实体