书签AngularJS前端(直接访问) - Spring Data Rest后端

时间:2015-07-29 14:36:58

标签: angularjs rest spring-data-rest hateoas hal-json

我已经开始实现一个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()
  • 使用前端网址中的id作为参数(或路径),并通过调用新的可用搜索关系来解析资源。
  • 缺点:这迫使我们手动重做Spring Data Rest自动生成的所有DTO,因此我们放弃了框架的目的之一。
  • 问题:有没有办法配置Spring自动公开那些id字段和findById方法?

2。使用自我关系

  • 使用findById() angular-hal方法
  • 获取实体的自我URI
  • 将其用作网页的参数,并通过调用新的$href('self')来解析资源
  • 缺点:应该在页面url之前和之后处理uri以防止由于地址栏中的另一个“http://”而导致的错误。我想在它上面做一些base64编码,但这很费劲。
  • 缺点:这会向全世界公开API网址,这些数据可能很重要,需要保持隐藏状态(即使可以通过调试人员观看网络流量也可以访问)。

第3。忘记HATEOAS

  • 不要理解关系和发现能力
  • 删除halClient.$get(resourceUri),只使用普通旧网址映射angular-hal
  • 缺点:这是落后的,感觉就像没有遵循指导方针......

那么,我错过了什么吗?在完整的RESTFul HATEOAS环境中访问数据的最佳实践是什么?

1 个答案:

答案 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> {    
}

我认为这可以很好地解决问题并允许以较低的价格直接从客户端访问实体