客户端如何知道REST中对象的正确结构?

时间:2013-02-03 08:25:07

标签: xml rest jax-rs

我正在使用Java和JBoss7与RESTEasy。我创建了我的RESTful服务和客户端来测试我的服务:

ClientRequest request = new ClientRequest(
         "http://localhost:8080/test/rest/cars");
request.accept(MediaType.APPLICATION_XML);

String input = "<car><carId>10.99</carId><carName>Ford</carName></car>";

request.body(MediaType.APPLICATION_XML, input);
ClientResponse<String> response = request.post(String.class);
System.out.println("Output from Server .... \n");
System.out.println(response.getStatus());

这完美无缺!这里唯一的问题是在客户端。我必须像String input = "<car><carId>10.99</carId><carName>Ford</carName></car>";中那样发送硬编码的XML,因为客户端没有我拥有的对象。

客户端将模仿从get方法接收的XML表示,这对于大型复杂资源来说可能很难。

  • 有没有办法让客户端知道他们想要发送的对象的正确结构,还是他们必须发送类型化的XML?

  • 我可以给客户端类似于WSDL或XSD的东西,或者是否会违反REST的限制?

  • 我见过人们会使用Xsteam和解组的解决方案,但他们认为客户端具有资源的类表示。

1 个答案:

答案 0 :(得分:1)

不要在客户端代码中对XML消息进行硬编码。 XML是服务和客户端之间传递的东西。

让我们假设您将相同的服务暴露在不同的位置,而另一个只能理解XML格式,而另一个只能理解JSON。如果您要将您的客户端与硬编码消息一起使用,您将只能调用会话XML的服务。记住REST是关于资源的表示。

  

因为客户端没有我拥有的对象。客户端将模仿他从get方法收到的XML表示,这对于大型复杂资源来说很难做到。

     

有没有办法让客户端知道他们想要发送的对象的正确结构,还是他们必须发送类型化的XML?

请考虑您的客户端是一个通常与对象一起使用的Java应用程序。对象代表资源(例如car),这是您的客户在内部使用的内容。

当需要调用服务时,您只需将这些对象编组为XML。当服务响应时,您将XML解组为对象。

根据使用的AcceptContent-Type标题,只需选择合适的marshaller / unmarshaller即可。然后,您甚至可以将某些内容作为XML发送并以JSON形式接收。

当然,RESTeasy clients可以使用与服务端相同的注释,甚至可以在服务和客户端之间重用某些Java类型(类),但这些Java类在客户端变得无用用其他技术编写:C#,Python,C ++等。

客户为什么要关心服务使用的类型?它应该只关心表示。在内部,客户端可以使用它想要的任何类型(独立于服务),并且只有在与服务通信时才与正确的表示进行通信。

  

我可以给客户端类似于WSDL或xsd的东西,或者是否会违反REST的约束?

这有点棘手。

REST是用于构建分布式系统的软件架构风格。不幸的是,不同的人对这种“风格”的理解不同,因此有很多所谓的RESTful API,它们只是简单地描述了使用哪些方法,在哪些URL以及将要发送回来的“类型”。

正如Roy T. Fielding自己所强调的那样,这是做错的REST方式:REST APIs must be hypertext-driven

RESTful客户端不需要事先了解要访问的URL或用于通信的“类型”。理解交换中使用的媒体类型就是它所需要的(我不是在谈论application/xml,它只是说明了没有语义或内部描述的消息格式。

结果为什么服务应该提供WSDL?实际上(虽然WSDL 2.0可以描述RESTful服务),实际上我们正在谈论WADL。但REST社区实际上并没有考虑到WADL,所以这也是is a matter of "style"

如果您正在“通过本书”进行REST,则不需要WADL。如果你实际上只有一个基于HTTP的界面,我认为你可以提供一个WADL来减轻其他程序员在开发客户端时的生活。

  

我见过人们会使用Xsteam和解组的解决方案,但他们认为客户端具有资源的类表示。

RESTeasy支持JAXB编组,因此只需很少的工作即可。