从外部 API 播放模型对象

Posted

技术标签:

【中文标题】从外部 API 播放模型对象【英文标题】:Play Model Objects from External API 【发布时间】:2013-05-27 20:44:43 【问题描述】:

我是 Play 2 框架的新手 v. 2.1.1 使用 Java,我正在寻找在不重复代码的情况下执行以下操作的最佳方法。

为了简化,我有一个使用外部 API 的 Play 2 后台。我不管理此 API,但我调用 REST 服务通过 api 执行操作。

此 API 的对象与 Play 2 模型对象完全相同。但我不想复制 api 对象来添加 Play 验证和其他注释。

有没有办法使用配置文件添加这种类型的行为?例如,我正在考虑像 Hibernate hbm's 之类的东西。

例如:

非托管 api 中的对象:(为简单起见,我省略了 getter 和 setter)

public class Entity
    public String field1;
    public String field2;

我想避免的对象:(为简单起见,我省略了 getter 和 setter)

public class Entity1

    @Required
    @NonEmpty
    @MinLength(3)
    public String field1;

    @Required
    @NonEmpty
    public String field2;

配置示例:(我需要这样的东西)

<class name="Entity1">
    <property name="field1" >
        <required/>
        <nonEmpty/>
        <minLength value="3"/>
    </property>
    <property name="field2" >
        <required/>
        <nonEmpty/>
    </property>
</class>

使用注释似乎比使用 xmls 或任何其他配置文件更好,所以我不一定要使用配置文件,我愿意接受任何解决此问题的建议。

谢谢

【问题讨论】:

我不确定您要在这里完成什么。 Play2 后台是什么意思?外部 API 是返回 json 数据的 REST API 吗? 嗨! Backoffice 是一个 Web 应用程序,它调用 REST 服务以通过 api 执行操作。 您能解释一下如何从 API 调用生成Entity 对象吗?从那时起,您将更容易了解如何从 Play2 的验证功能中受益。 你不能创建一个包含两个应用程序共享的值对象的公共库吗? 这两个应用程序可能是我的,但我只能控制网络应用程序。 api是其他团队给的,我不能修改。 【参考方案1】:

我看不出在像 XML 这样的非类型安全描述符中复制 API 模型比使用类型安全语言更好。此外,我不想将我的模型和应用程序耦合到我控制下的 API 中的模型。

我认为在 Java/Scala 中复制模型并使用像推土机这样的简单 bean 复制器在两者之​​间移动要好得多。

【讨论】:

【参考方案2】:

一个问题是 ebean 作为持久性提供者 - 在 ebean 中,没有办法像在 hibernate 中那样将 bean 持久性配置外部化(sql 查询除外)。是否可以切换持久性提供程序?游戏似乎允许这样做。

由于您写道您无法修改实体源代码并且您不想复制源代码,所以我看到的唯一另一种可能性是字节码增强。

您需要的是一个库,它允许您将 xml 文件中的注释外部化。该库将使用检测 api,在 jvm statup 读取 xml 文件并修改每个列出的类的字节码,以便在运行时为类和字段添加注释。

这种方法有两个问题:

    没有这样的库(至少我找不到) Play 和 EBean 使用它们自己的代理/类加载器以允许热部署和持久性

第一个问题是简单有趣的部分,例如https://today.java.net/pub/a/today/2008/04/24/add-logging-at-class-load-time-with-instrumentation.html。使用 javaassist 可以很容易地为类和字段添加注释。从 xml 到注释的映射是直截了当的。这将是一个不错的开源项目。

第二个问题看起来要困难得多,因为您必须安装注释代理,以便它在播放和 ebean 开始解析注释之前执行。

【讨论】:

【参考方案3】:

我不清楚为什么不能在你自己的应用程序中添加注释,但是如果你有这样的限制,为什么不扩展类,覆盖变量,添加注释,并将其用作 EBean型号?

【讨论】:

【参考方案4】:

Play 具有动态表单,可让您根据键值对映射进行验证。如果验证是您想要的,您可以将实体的数据复制到地图并进行验证。

【讨论】:

【参考方案5】:

简单的答案:如果代码行相同,并不总是存在代码重复。

Robert C. Martin 在他的一次演讲中展示了这一点:单一责任原则。有两种方法可以打破这一原则:一方面,一个代码片段中的两个职责,另一方面,一个职责在两个代码片段中独立处理。

代码重复是一种责任和语义,而不是相同的代码行(这最多可能是代码重复的一个指标)。

在您的情况下,职责是明确分开的:您有一个外部 API 和您的代码。所以没有代码重复。

【讨论】:

以上是关于从外部 API 播放模型对象的主要内容,如果未能解决你的问题,请参考以下文章

如何从外部 API 填充 django 模型?

具有来自外部 Api 的缓存数据的 Falcor 模型

Django:将来自外部 API 的数据映射到模型中?

从 Tensorflow 对象检测 API 动物园模型导出错误的冻结图

如何从 segue 方法初始化模型

通过 Spotify Apps API 创建播放列表文件夹