API设计选择 - XML接口中的命名空间

时间:2013-05-03 23:33:32

标签: web-services api rest api-design

我正在设计一个新的API,我正在努力做出一些决定。我已经阅读了大量有关SOAP与REST的博客,我使用了流行的API(Paypal,亚马逊等)作为我的指南。

我最终在我的API中有两个端点:一个用于SOAP,另一个用于REST(XML)。 SOAP看起来很不错,但XML界面看起来有些奇怪。我称之为“奇怪”,因为我最终在某些标签中使用了命名空间。例如:

[SAMPLE1]

<EnvelopeRequest xmlns:c1='http://foobar/CarrierX'>
    <Weight>1.0</Weight>
    <PostmarkDate>5/3/2013</PostmarkDate>
    <c1:ShippingMethod>Ground</c1:ShippingMethod>
    <c1:Notification>a@b.com</c1:Notification>
</EnvelopeRequest>

[SAMPLE2]

<EnvelopeRequest xmlns:cs='http://foobar/SpecialCarrier'>
    <Weight>1.0</Weight>
    <PostmarkDate>5/3/2013</PostmarkDate>
    <cs:Shape>Flat</cs:Shape>
</EnvelopeRequest>

XML接口具有名称空间的原因是因为它是从类定义(具有一些继承)自动生成的。我们正在使用WCF btw。这适用于SOAP(WSDL源自同一个类),因为SOAP隐藏了客户端代理中的所有丑陋。但是,在查看了许多REST / XML服务之后,我认为我没有经常使用名称空间。这也有点让我感到害怕,因为我觉得我很想在不久的将来拥有一个JSON接口,而JSON不支持命名空间。

我决定使API SOAP友好,这是因为我们的许多客户都使用了在SOAP上蓬勃发展的企业解决方案。但是最近,随着Python和Ruby的日益普及,新客户似乎更频繁地采用,我开始猜测我最初的决定。困扰我的主要事情是XML接口中的命名空间,但它真的是一个问题吗? REST / XML API中的命名空间是否是一个很大的禁忌,我应该改变我的设计?

如果我确实更改了我的设计,那么我的(之前的2个)请求将如此:

[SAMPLE1]

<EnvelopeRequest>
    <Weight>1.0</Weight>
    <PostmarkDate>5/3/2013</PostmarkDate>
    <CarrierX>
        <ShippingMethod>Ground</ShippingMethod>
        <Notification>a@b.com</Notification>
    </CarrierX>
</EnvelopeRequest>

[SAMPLE2]

<EnvelopeRequest>
    <Weight>1.0</Weight>
    <PostmarkDate>5/3/2013</PostmarkDate>
    <SpecialCarrier>
        <Shape>Flat</Shape>
    </SpecialCarrier>
</EnvelopeRequest>

是的,这将允许我将来拥有一个JSON接口。

2 个答案:

答案 0 :(得分:2)

删除名称空间将是一个问题,如果这样做,您可能会在给定的消息中产生歧义的可能性。某个地方的某个人是否有可能创建一个EnvelopeRequest消息,其中Shape元素可能以多种方式解释(通过代码或读取消息的人)?引入命名空间的原因是为了排除这种可能性。像WCF的自动生成器这样的工具在一般情况下无法回答这个问题,所以他们在谨慎方面犯了错误。

只有您可以知道可能的有效消息集。根据我的经验,通常最好删除命名空间,以免混淆您的用户/客户端。我可能会改变这种偏好有几个原因:

  • 我希望我的消息格式能够广泛使用并与其他格式混合使用。 (一个很好的例子是Atom联合格式)
  • 我正在使用其他人广泛使用的(和命名空间)格式,并计划将其与我自己的格式混合(例如,在我的消息中嵌入XHTML)。
  • 我希望在相同格式的消息中嵌入给定格式的消息(例如,生成XSLT样式表的XSLT样式表)。

在后一种情况下,您可能会发现使用命名空间通过使用不同的前缀将内部消息与携带它的消息分开是方便的(尽管不是绝对必要)。我不认为这些案件经常适用。

答案 1 :(得分:0)

我会思考为什么你首先拥有命名空间,那些是一些奇怪的有效载荷。

但是,无论如何,命名空间并不是什么大问题。命名空间几乎不可避免地与XPath和XSL发生冲突(因为它们往往是名称空间感知),但是当批量使用文档时,很多时候人们完全忽略名称空间组件,所以最终没有区别。

我会清理命名空间,以便在语义上清理它们,但不一定是为了消费者。从实际的角度来看,这并不是什么大不了的事。