首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何通过带有ALPS/HATEOAS元数据的Spring数据MongoDB存储库公开一个新的REST方法?

如何通过带有ALPS/HATEOAS元数据的Spring数据MongoDB存储库公开一个新的REST方法?
EN

Stack Overflow用户
提问于 2015-07-22 22:39:22
回答 1查看 1.1K关注 0票数 3

如何将MongoRepository扩展类中的新方法公开给生成的REST,并包含相同的ALPS/HATEOAS元数据、链接等。

我有一个常用的Spring数据MongoDB存储库:

代码语言:javascript
复制
public interface CollectionRepository extends Repository<Collection, String> {    
    // Simple queries
    Collection findFirstByName(@Param("name") String name);   
}

现在,我想添加另一个方法,并将它集成到生成的Repository中,以便它与QueryDSL生成的元素一起包含在{存储库}/集合/搜索响应中。

我不得不使用PersistentEntityResourceAssembler和PersistentEntityResource来提供参数,并将响应转换成适当的格式。2)自动生成HATEOAS/ALPS元数据,使父URL在API浏览器中显示带有参数的方法。

这是我的定制控制器。注意,我必须在模板自动装配上指定一个@限定符,因为我有多个数据库,而且它选择了错误的默认数据库。

代码语言:javascript
复制
@Component
@RepositoryRestController
@RequestMapping(value = "{repository}/search")
public class CollectionRepositoryController implements ResourceProcessor<RepositorySearchesResource> {

    @Autowired private EntityLinks entityLinks;
    @Autowired private PagedResourcesAssembler pagedResourcesAssembler;
    @Autowired Repositories repositories;
    @Autowired
    @Qualifier("mongoTemplateCollections")
    private MongoTemplate mongoTemplate;
    private final CollectionRepository repository;
    @Autowired
    public CollectionRepositoryController(CollectionRepository repo) {
        repository = repo;
    }
    @SuppressWarnings("unchecked")
    @RequestMapping(value = "findText", method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE)
    public PagedResources<PersistentEntityResource> findText(
            Pageable pageable, @RequestParam(value = "findText", required = false) String findText,
            PersistentEntityResourceAssembler resourceAssembler) {
        TextCriteria criteria = TextCriteria.forDefaultLanguage().matchingAny(findText);
        Query query = TextQuery.queryText(criteria).sortByScore();
        List<Collection> collections = mongoTemplate.find(query, Collection.class);
        Page<Collection> page = new PageImpl<Collection>(Arrays.asList(new Collection()), pageable, pageable.getOffset());

       // What goes below here to convert List<Collections> into PersistentEntityResource ?

        PersistentEntity<?, ?> persistentEntity = repositories.getPersistentEntity(Collection.class);
        for(Collection collection : collections) {
            PersistentEntityResource collectionResource = PersistentEntityResource.build(collection, persistentEntity).
                    withLink(new Link("/collection/" + collection.getId())).build();
            Log.info("collections resource: " + collectionResource);
        }

        return pagedResourcesAssembler.toResource(page, resourceAssembler);
    }

    // https://stackoverflow.com/questions/29570962/how-to-add-custom-methods-to-spring-data-rest-jpa-implementation-and-leverage-ha
    @Override
    public RepositorySearchesResource process(RepositorySearchesResource resource) {
        LinkBuilder lb = entityLinks.linkFor(Collection.class, "name");
        resource.add(new Link(lb.toString() + "/search/findText{?findText}", "findText"));
        return resource;
    }
}

我也创建了这个程序,但我不知道如何/将它连接到何处:

代码语言:javascript
复制
@Component
public class CollectionResourceAssembler implements ResourceAssembler<Collection, Resource<Collection>> {

    @Autowired
    EntityLinks entityLinks;

    @Override
    public Resource<Collection> toResource(Collection collection) {
        Resource<Collection> resource = new Resource<Collection>(collection);

        final LinkBuilder lb = entityLinks.linkForSingleResource(Collection.class, collection.getId());
        resource.add(lb.withSelfRel());
        resource.add(lb.slash("answers").withRel("answers"));
        // other links

        return resource;
    }
}

我遇到麻烦的地方是“下面是什么”,就像奥利弗建议的那样:

调用存储库并使用可注入到处理程序方法中的PersistentEntityResourceAssembler来生成要返回的PersistentEntityResource。

而且,我真的需要使用ResourceProcessor.process()方法手动设置ALPS/HATEOAS数据吗?还是有一个使其自动化的诀窍?

这是一个无价之宝。我很肯定这里面没有任何东西,所以这说明了如何做到这一点,至少在我需要的手持水平上是这样。这一个也相当接近:为REST Spring HATEOAS控制器定义资源汇编程序,但也假设比我知道的更多。

EN

回答 1

Stack Overflow用户

发布于 2015-07-23 14:12:06

tl;dr

它需要存储库和控制器的自定义实现。

详细信息

我们必须确保我们不会迷失在你在这里提到的所有不同方面。我试着把树枝从下往上解开:

执行MongoDB脚本

正如使用MongoDB执行脚本的参考文档声明的(您已经发现),by MongoTemplateScriptOperations提供了该功能。因此,如何使用该API应该是清楚的。

通过Spring数据存储库执行脚本

接下来需要的是通过存储库抽象来执行这些脚本。要避免在这里使用浴缸水将婴儿抛出,请确保我们理解存储库的用途:它模拟聚合根的集合并访问它,而不公开底层的持久性机制。在存储库中公开像ExecutableMongoScript这样的类型会破坏后一个特性。因此,这里正确的方法是为该特定功能定制一个自定义实现,如关于Spring数据仓库的参考文档中所述。

通过REST公开功能

我假设您是在引用Spring的特性,以便在您的问题中公开存储库查询方法的专用资源。Spring数据REST目前只自动公开声明性查询方法,主要原因是很难推理正确的HTTP方法来支持自定义实现,因为我们无法猜出方法内部发生了什么。

推荐的方法是使用自定义控制器公开自定义存储库查询方法,使用适合您的目的的@RequestMapping,调用存储库,并使用可注入到处理程序方法中的PersistentEntityResourceAssembler生成要返回的PersistentEntityResource

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31575259

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档