当前位置: 首页 > 知识库问答 >
问题:

使用Spring HATEOAS将枚举公开为REST API的正确方法是什么(通过Spring Data REST)

邓英卓
2023-03-14

我正在尝试将HATEOAS与Spring HATEOAS一起使用,并且需要将enums公开为带有Spring HATEOAS的REST API。

我尝试了以下三种方式:

@RestController
@RequestMapping(path = "/fruits")
public class FruitResourceController {

    @RequestMapping(method = RequestMethod.GET)
    public Fruit[] fruits() {
        return Fruit.values();
    }

    // NOTE: The `produces` attribute is only for browsers.
    @RequestMapping(path = "/with-resource", method = RequestMethod.GET,
            produces = MediaTypes.HAL_JSON_VALUE)
    public Resource<Fruit[]> fruitsWithResource() {
        Resource<Fruit[]> resource = new Resource<Fruit[]>(Fruit.values());
        Link selfLink = linkTo(methodOn(FruitResourceController.class).fruitsWithResource())
                .withSelfRel();
        resource.add(selfLink);
        return resource;
    }

    // NOTE: The `produces` attribute is only for browsers.
    @RequestMapping(path = "/with-resources", method = RequestMethod.GET,
            produces = MediaTypes.HAL_JSON_VALUE)
    public Resources<Fruit> fruitsWithResources() {
        Resources<Fruit> resources = new Resources<Fruit>(Arrays.asList(Fruit.values()));
        Link selfLink = linkTo(methodOn(FruitResourceController.class).fruitsWithResources())
                .withSelfRel();
        resources.add(selfLink);
        return resources;
    }

}

但是我不知道哪个是HATEOAS的正确方法。任何建议或参考都将不胜感激。

作为参考,我有以下Spring Data REST配置:

@Configuration
public class SpringDataRestConfig {

    @Bean
    public ResourceProcessor<RepositoryLinksResource> repositoryLinksResourceProcessor() {
        return new ResourceProcessor<RepositoryLinksResource>() {
            @Override
            public RepositoryLinksResource process(RepositoryLinksResource resource) {
                Link fruitsLink = linkTo(methodOn(FruitResourceController.class).fruitsWithResources())
                        .withRel("fruits");
                resource.add(fruitsLink);
                return resource;
            }
        };
    }

}

请参见以下示例项目:

https://github.com/izeye/spring-boot-throwaway-branches/blob/data-jpa-and-rest/src/main/java/com/izeye/throwaway/SpringDataRestConfig.java https://github.com/izeye/spring-boot-throwaway-branches/blob/data-jpa-and-rest/src/main/java/com/izeye/throwaway/FruitResourceController.java

---更新日期:2016.01.04

使用ALPS(/profile)获得枚举列表看起来不错,但我不确定这是一种正确的方法。

共有1个答案

宗政博文
2023-03-14

HATEOAS的轮廓看起来是正确的地方。但是当你手里拿着锤子时,一切看起来都像钉子。

数据验证不是HATEAOS规范的一部分,您不应该尝试“用锤子粉刷墙壁”。

您最好使用为此而设计的解决方案;窗体。我应该研究JSON-Schema及其扩展Json-Forms。

https://jsonforms.io/

这是通过UI定义数据输入的标准化解决方案。只是代码endpoint释义HATEAOS命名约定

/表单/${entityname}

作为 /profile的扩展/替代,您可以很容易地修改Spring以将其包含到根的HATEOAS“_links”中

返回同名实体的硬编码JSON表单模式。您还可以使用交叉连接半自动执行此操作,以便它只返回当前实体的匹配键/字段。所以,若实体发生变化,它不会完全破坏您的UI。然后,您可以使用大量代码实现全自动,这些代码通过反射读取实体类,并自动为您的实体生成JSON表单模式定义。

就像这个Java的伪代码

entity.getFields().forEach(
  if (isEnumeration(field)) {
     sb.append( 
         field.getName() + ": {"
         + "type: string,"
         + "title: " + localize(field.getName() + ","
         + "enum: " Arrays.toString(field.values()) + ","
         + "required: " isNullable(field) 
         + "    },"
     );
    continue; 
  );
  if (isString(field)) {
    ...

您自己的数据模式的约束是可行的。如果您的代码

 类似资料:
  • 问题内容: 作业:剪刀石头布游戏。 我创建了一个枚举: 从中我想比较各种价值观来决定谁是计算机还是人。设置值就可以了,并且比较也可以正常工作(纸张覆盖岩石,岩石压碎剪刀,剪刀切碎纸张)。但是,我不能束手无策。只要有平局,该用户即被宣布为获胜者。 唉唉......废话......这将澄清:是一个具有价值,或。我无法用比较来,正如你可以看到下面,是铸造类型从我的。 我猜这是一个不等于或无法匹配的问题,

  • 我听到一些人建议在C++中使用枚举类,因为它们的类型安全。 但这到底意味着什么呢?

  • 问题内容: 即使在使用Java Swing一年以上之后,对我来说,它仍然像魔术一样。如何正确使用BufferStrategy,尤其是方法? 我想添加一个JFrame和一个Canvas,然后进行绘制。我还希望能够调整()画布的大小。每次我调整Canvas的大小时,似乎都会被浪费掉,或者变得毫无用处,因为在上使用并没有真正做任何事情。另外,它具有怪异的不确定性行为,我不知道如何正确同步它。 这就是我的

  • 问题内容: 我想在Linux上使用该机制。我希望我的应用程序知道何时更改了文件。能否请您提供给我一个示例,该怎么做? 问题答案: 文档(来自具有inotify的Monitor文件系统活动) 在C API 提供了三个系统调用来构建各种文件系统监视器: 在内核中创建子系统的实例,并在成功和失败时返回文件描述符。与其他系统调用一样,如果失败,请检查诊断。 顾名思义,它增加了一块 手表 。每个监视都必须提

  • 问题内容: 需要帮助,以了解如何在UIKit中使用prepareForReuse()。该文件说 您只应重置与内容无关的单元格属性,例如Alpha,编辑和选择状态 但是如何重置单个属性属性(例如isHidden)呢? 假设我的单元格有2个标签,我应该在哪里重置: 标签文本 label.numberOfLines label.isHidden 我的tableView(_:cellForRowAt :)

  • 一段时间以来,我一直试图将我的tableview工作作为一种电子表格,通过背景线程进行更新,当单元格更新时,它会亮起几秒钟(更改样式),然后返回到原始样式。我已经知道,我不能直接在表格单元格中存储和设置样式,我需要某种支持类来保存这些数据。但是tableview“重用”单元格(使用相同的单元格处理不同的数据)的行为真的很奇怪。当所有单元格都适合屏幕时,它对我来说完美无瑕,但一旦我放置大约100个单