Bookmark AngularJS 前端(直接访问)- Spring Data Rest 后端
Bookmark AngularJS frontend (direct access) - Spring Data Rest backend
我已经开始实施 Web 前端来操纵 Spring Data Rest
通过传统关系数据库提供的 RESTful 服务。这是用 AngularJS
完成的,我发现 angular-hal
库非常适合 Spring Data Rest
的 HATEOAS
哲学和形式主义。
例如,我只需要知道第一个 API 端点('/'),然后我的所有查询都通过关系完成,而不关心 url。
我遇到的问题是能够直接访问显示我的实体之一的页面。
让我们以联系人存储库为例。如果我从主页开始,然后浏览联系人列表,然后选择我想详细查看的联系人,就没有问题。
但我无法直接访问显示联系人详细信息的页面:资源从列表控制器注入到编辑控制器,而编辑控制器无法知道 url如果列表控制器未告知则请求。
根本问题是,对于 Spring Data Rest
,实体的 id
(不在 JSON 中)没有 public 字段,并且存储库没有 API relation
按id搜索。
我想过一些解决方案,但我都不喜欢。
1.在后端解决
- 为所有需要添加书签的实体添加一个
Projection
方法getId()
- 在仓库界面添加对应的
findById()
- 使用前端url中的id作为参数(或路径),调用新的可用搜索关系解析资源
- 缺点:这迫使我们手动重做所有由 Spring Data Rest 自动生成的 DTO,因此我们失去了框架的目的之一。
- 问题 : 有没有办法配置 Spring 自动公开那些 id 字段和 findById 方法?
2。使用自我关系
- 使用
angular-hal
$href('self')
方法获取实体的自身URI
- 将其用作页面的参数并通过在其上调用新的
halClient.$get(resourceUri)
来解析资源
- 缺点: uri 应该在被放入页面之前和之后进行处理 url 以防止由于地址栏中的另一个 "http://" 而导致的错误.我想在上面做一些 base64 编码,但这很消耗。
- 缺点:这将 API url 暴露给世界,并且这些数据可能很关键并且需要保持隐藏(即使这将也可以通过监视网络流量的调试器访问。
3。忘掉 HATEOAS
- 不要为关系和发现能力而烦恼
- 删除
angular-hal
并仅使用 $resource
和普通的旧 url 映射
- 缺点:这是在倒退,感觉不遵循指导方针...
那么,我是不是漏掉了什么?关于在完整 RESTFul HATEOAS 环境中访问数据的最佳做法是什么?
我找到了 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);
}
}
然后我让所有我希望 id 公开的实体继承自一个公共抽象 class
@MappedSuperclass
public abstract class AbstractEntity {
@Id @GeneratedValue
Long id;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
此摘要 class 由 @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> {
}
我认为这是一个很好的解决方法,允许以较低的价格从客户端直接访问实体
我已经开始实施 Web 前端来操纵 Spring Data Rest
通过传统关系数据库提供的 RESTful 服务。这是用 AngularJS
完成的,我发现 angular-hal
库非常适合 Spring Data Rest
的 HATEOAS
哲学和形式主义。
例如,我只需要知道第一个 API 端点('/'),然后我的所有查询都通过关系完成,而不关心 url。 我遇到的问题是能够直接访问显示我的实体之一的页面。
让我们以联系人存储库为例。如果我从主页开始,然后浏览联系人列表,然后选择我想详细查看的联系人,就没有问题。
但我无法直接访问显示联系人详细信息的页面:资源从列表控制器注入到编辑控制器,而编辑控制器无法知道 url如果列表控制器未告知则请求。
根本问题是,对于 Spring Data Rest
,实体的 id
(不在 JSON 中)没有 public 字段,并且存储库没有 API relation
按id搜索。
我想过一些解决方案,但我都不喜欢。
1.在后端解决
- 为所有需要添加书签的实体添加一个
Projection
方法getId()
- 在仓库界面添加对应的
findById()
- 使用前端url中的id作为参数(或路径),调用新的可用搜索关系解析资源
- 缺点:这迫使我们手动重做所有由 Spring Data Rest 自动生成的 DTO,因此我们失去了框架的目的之一。
- 问题 : 有没有办法配置 Spring 自动公开那些 id 字段和 findById 方法?
2。使用自我关系
- 使用
angular-hal
$href('self')
方法获取实体的自身URI - 将其用作页面的参数并通过在其上调用新的
halClient.$get(resourceUri)
来解析资源 - 缺点: uri 应该在被放入页面之前和之后进行处理 url 以防止由于地址栏中的另一个 "http://" 而导致的错误.我想在上面做一些 base64 编码,但这很消耗。
- 缺点:这将 API url 暴露给世界,并且这些数据可能很关键并且需要保持隐藏(即使这将也可以通过监视网络流量的调试器访问。
3。忘掉 HATEOAS
- 不要为关系和发现能力而烦恼
- 删除
angular-hal
并仅使用$resource
和普通的旧 url 映射 - 缺点:这是在倒退,感觉不遵循指导方针...
那么,我是不是漏掉了什么?关于在完整 RESTFul HATEOAS 环境中访问数据的最佳做法是什么?
我找到了 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);
}
}
然后我让所有我希望 id 公开的实体继承自一个公共抽象 class
@MappedSuperclass
public abstract class AbstractEntity {
@Id @GeneratedValue
Long id;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
此摘要 class 由 @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> {
}
我认为这是一个很好的解决方法,允许以较低的价格从客户端直接访问实体