Spring Boot: Add Non-Repository REST Controller to HAL Links

為{幸葍}努か 提交于 2020-01-16 08:33:20

问题


The problem:

I have a simple Spring Boot app, using Spring Data REST and HATEOAS, with a JPA Entity class which calls a MySql Function (not a table). The rest of my repos are displayed in a nice HAL set of hyperlinks, but this one function is not discoverable (not in the list). How do I add it into the HAL links?

@Entity(name = "GetOptionsForStyle")
@Table(name = "get_options_for_style")

@NamedNativeQueries({
    @NamedNativeQuery(name = "getOptionsByStyleId", 
    query = "SELECT `f1`.`get_options_for_style`(?) AS `value`, FLOOR(1 + (RAND() * 10000)) AS `id`", resultClass = GetOptionsForStyle.class) })

/**
 * GetOptionsForStyle
 */
public class GetOptionsForStyle implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue
    private Integer id;

    private String value;

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }
}

The Entity is exposed to the Spring Boot app in a simple repo:

@Repository
public class FunctionsRepo {

    @PersistenceContext
    private EntityManager manager;

    public GetOptionsForStyle getOptionsForStyle(Integer styleId) {

        GetOptionsForStyle getOptionsForStyle = manager
                .createNamedQuery("getOptionsByStyleId", GetOptionsForStyle.class)
                .setParameter(1, styleId)
                .getSingleResult();

        return getOptionsForStyle;
    }

}

I am using Spring Data REST, and I would like to provide a link to this entity in the HAL links created automatically by SDR, but SDR runs on repo interfaces to entities for tables, not repo implementations calling named queries.

I can return the result of the MySql Function via a standard controller, but the link is not integrated into HAL:

@BasePathAwareController
public class SitesRestController {

    private FunctionsRepo funcRepo;

    SitesRestController(FunctionsRepo funcRepo) {
        this.funcRepo = funcRepo;
    }

    @GetMapping(path="func/get_options_for_style/{styleId}")
    @ResponseBody
    public ResponseEntity<GetOptionsForStyle> getOptionsForStyle(@PathVariable("styleId") final Integer styleId) {

        GetOptionsForStyle optForStyle = funcRepo.getOptionsForStyle(styleId);
        return new ResponseEntity<GetOptionsForStyle>(optForStyle, HttpStatus.OK);
    }

}

A similar question on StackOverflow (Q) points to these two answers (A and B). These answers both use ResourceProcessor, which was removed in v1 of spring-hateoas. The "spring-hateoas-examples/spring-hateoas-and-spring-data-rest" GitHub repo by GregTurn (one of the Spring HATEOAS contribs) uses a standard Repo interface also. I can get this to work on regular repo interfaces.

Is it possible to integrate into the HAL links produced by Spring Data REST? Is there a way to get a handle to that set of links before it is rendered? I can get a RepresentationModelProcessor to catch an entity before it is rendered, perhaps there is a similar hook to the main HAL links?

来源:https://stackoverflow.com/questions/59314771/spring-boot-add-non-repository-rest-controller-to-hal-links

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!