【问题标题】:What is the right way exposing enums as REST API with Spring HATEOAS (via Spring Data REST)使用 Spring HATEOAS 将枚举公开为 REST API 的正确方法是什么(通过 Spring Data REST)
【发布时间】:2016-04-02 02:03:58
【问题描述】:

我正在尝试将 HATEOAS 与 Spring HATEOAS 一起使用,并且需要通过 Spring HATEOAS 将 enums 公开为 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) 获得枚举列表看起来不错,但我不确定这是一种正确的方法。

【问题讨论】:

  • produces 属性仅适用于浏览器” - 你认为它是为什么呢?
  • @zeroflagL 对不起,令人困惑的评论。这意味着它只存在于浏览器强制呈现为 JSON,并不意味着它只影响浏览器。
  • expsing enums 到底是什么意思?你想公开一个静态的、只读的字符串值列表吗?那你为什么不干脆那样做呢?只需在 REST 控制器中返回枚举本身 Fruit.values() 即可。 Spring 会自动将 HTTP 响应到一个字符串数组。
  • 关于 HATEOAS:这只是表示的一种格式(带有链接、href 和资源)您希望将哪些链接添加到您的枚举值中?你能做到吗?但是为了什么?据我了解,这只是一个静态的字符串列表。没有 POST 到那个休息端点或者有吗?
  • 为什么这么多赞?!

标签: rest spring-data-rest hateoas spring-hateoas


【解决方案1】:

HATEOAS 个人资料似乎是正确的地方。但是当你手里拿着锤子时,一切看起来都像钉子。

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

使用为此而设计的解决方案会好得多;形式。我应该研究一下 JSON-Schema 和它的扩展 Json-Forms。

https://jsonforms.io/

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

/form/${entityname}

作为 /profile 的扩展/替代,您可以相当容易地修改 Spring 以将其包含到根和实体的 HATEOAS“_links”中。但这不是 HATEOAS! (或斯巴达!)

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

就像这个Java-ish伪代码

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)) {
    ...

你自己的数据模式的约束是可行的。 如果您的代码和 ER 干净且一致。您还可以添加更多 UI 验证信息,例如 regexp 验证。对于这个标准,React、Angular 和 Vue 有现成的 UI 库和组件。材质 UI 组件是基于此的,至少它们的 Forms - 组件。

【讨论】:

    猜你喜欢
    • 2015-05-03
    • 2016-06-23
    • 2013-10-31
    • 2018-07-23
    • 2014-03-07
    • 1970-01-01
    • 2023-03-09
    • 2018-02-23
    • 2014-07-05
    相关资源
    最近更新 更多