Restful 架构问题:(太多) 复杂对象的处理

3

好的,我被任命负责RESTful架构中服务器和客户端(内部使用)部分的工作(使用restlet)。

我们有一个暴露Post操作的资源。以下是一个简化版本:

public class UserResource {

    @Post
    public Representation create(UserRegistration registration) {
        SomeService.getInstance().createUser(registration);
        return new XstreamRepresentation(new RegistrationResponse(registration.getUniqueCode()););
    }

最近几个月,我们一直是唯一使用这些服务的人,因此域对象在客户端和服务器端之间共享……一切都很顺利。

现在我们需要记录这些资源并让其他客户端使用它们,一些“问题”已经出现,这让我觉得这个API可能有点过于复杂。

例如,这个Post服务。内部方法接受复杂类型UserRegistration

public class UserRegistration implements Serializable {

    private Profile profile;
    private Boolean someBooleanProperty;

    public UserRegistration(Profile profile) {
        this(profile, true);
    }

    public Profile getProfile() {
        return profile;
    }

    public boolean isSomeBooleanProperty() {
        return someBooleanProperty;
    }

}

这句话中的另一个复杂对象是Profile。

public class Profile {

    private String nickname;
    private String email;
    private String password;
    private String firstname;
    private String lastname;
    private Date birthDate;
    private String phone;
    private Address address;
    private GenderType gender;
    private String subscriptionSite;
    private Date privacyAcceptanceDate;
    private Date subscriptionDate;
    private String activationCode;
    private String socialSecurityNumber;
    ...

这里使用了许多复杂类型,这让我感到困扰。

我不知道该如何记录这些复杂对象(除了列出这些复杂对象的内部属性的长长列表),或者我已经迷失了方向。

我的问题是: 我是否需要简化? 这种架构设计很糟糕吗? 一些builder方法能解决问题吗?

2个回答

3
通过在客户端和服务器之间共享域实体类型,您(不是特指您)已经完全违背了REST的原意。RESTful系统应该只分享媒体类型和链接关系。像您这样共享类型,在SOAP中要容易得多,因为WSDL允许工具包处理保持客户端和服务器类型同步的细节。
REST的全部内容都是减少客户端和服务器之间的耦合,以使它们能够独立演化。显然,如果您有一组大量共享的类型,那将会很困难,这就是为什么您目前有这种糟糕的感觉。
我对这个问题采取的解决方案是定义两种媒体类型。一种是通用实体数据容器。让我们称其为BusinessDocument,另一种称为BusinessLayout。客户端使用BusinessDocument从服务器检索所有数据,而BusinessLayout提供“数据绑定”信息,使客户端知道在我的UI中显示不同业务数据的位置。
通过这样做,我能够构建一个客户端,它真的不理解它正在处理的数据的具体内容,它只知道如何在UI上显示它,以便用户进行交互。通过这样做,我能够使用单个媒体类型来描述数百个不同的业务实体。

你说得对,@Darrel。整个“复杂性”都源于我们是唯一的客户(并共享域实体)。 现在我负责以某种方式“简化”整个过程(或使其更加RESTful),而不会破坏我们自己的客户端。 我必须补充说明,Restlet 一点也没有帮助我。 - mfirry
@tixe 请查看Hal(http://stateless.co/hal_specification.html),并考虑如何使用内容协商来允许服务器提供资源的多个表示形式。这将使您能够支持旧格式,同时引入一组新的耦合度较低的表示形式。 - Darrel Miller

0

没有必要将Java客户端提供给外部消费者。您的API应该能够回答任何Http客户端。存在共享对象的Java客户端可能取决于不同的因素,但不应影响您向第三方消费者公开REST API的方式。

因此,我建议开始编写一个纯HTTP客户端,使用Apache Commons HTTP,以查看您的REST API的行为。

服务器对象复杂也不应该引起API的任何兴趣。如果旧系统是围绕数据建模对象设计的,我认为这是一个坏主意,那么这是您需要处理的事情。从REST API中,您始终只接收文本、XML或JSON,并且最终需要将其解析为Java对象,例如ORM + RDBMS支持的系统。如果您可以存储Json,例如在文档数据库中,您就没有这个问题,但是,再次强调,这与REST API本身无关,但您需要一个将JSON转换为Java对象的层。

Restlet可以帮助您完成这项工作,当然,这样复杂的对象不容易自动转换。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接