RESTFul服务和“GetCapabilities”

时间:2014-01-31 11:05:00

标签: rest servicestack restful-architecture

我正在编写一个REST服务,它处理存储在数据库中的SomeKindOfResource

不要问我为什么(不要!)但由于某些原因,相应的基础表具有可变数量的列。这是它的方式,我无法改变它。

因此,当我发出GET /SomeKindOfResources/{id}时,我的DTO(稍后序列化为JSON)可能包含可变数量的“字段”。我知道如何处理动态对象/序列化部分。我的问题更多的是关于事物的哲学方面。

假设我的客户想要知道调用GET /SomeKindOfResources/{id}所返回的字段列表是什么,例如,该列表确定了可以在以后使用的过滤器列表SomeKindOfResources。基本上,我需要类似“GetCapability”的东西。

您将如何以RESTful方式处理此类场景?

1 个答案:

答案 0 :(得分:4)

如果我正确理解您的要求,您希望为具有动态字段的特定对象(即通过Id)返回元数据(如)响应,因此您的客户端知道它将在接收时收到的字段类型请求该对象。

请注意:动态DTO不是RESTful。 DTO的重点是它是一份商定的合同。它不应该更改,因此没有RESTful规则来处理您的用例。

如果您要实现这一点,这些是三种可能的方法。

元数据路线:

在您的服务中创建新路由,因为标准ServiceStack MetadataFeature未涵盖此方案,因为它仅适用于静态DTO。所以创建这样的东西:

[Route("/SomeKindOfResources/{Id}/metadata", "GET"]

然后,您希望对该路由的响应向您的客户端描述字段。这是阴天的地方。 MetaDataFeature使用XSD来描述您的标准DTO,您可以根据您对可用字段的数据库查找,编写您的操作以生成描述您的字段的XSD响应。但是,您的客户会知道如何解析XSD吗?由于您的使用不是标准的,并且不能期望客户端以RESTful方式处理它,因此您可能只想使用简单的响应类型,例如基本上只返回字段名称的Dictionary<string,Type>(),以及基础类型。这适用于简单的内置类型,例如stringintbool等,但自定义类方案将更难处理,例如List<MySpecialType>

伪客户端代码:

var fieldMetaData = client.get("/SomeKindOfResources/123/metadata");
var result = client.get("/SomeKingOfResources/123");

Example XSD Metadata Response.

OPTIONS标题:

但是,根据RFC2616 §9的建议,您可能希望考虑使用OPTIONS动词而非GET请求添加到/metadata前面的另一个请求。

  

此方法允许客户端确定与资源相关联的选项和/或要求,而不会暗示资源操作或启动资源检索。

伪客户端代码:

var fieldMetaData = client.options("/SomeKindOfResources/123");
var result = client.get("/SomeKindOfResources/123");

但请记住,REST中的OPTIONS通常用于设置CORS。

ServiceStack JSON __type响应:

当ServiceStack返回JSON时,您可以告诉ServiceStack.Text序列化程序在属性调用__type中包含返回类型信息。虽然这对您的客户来说可能并不容易解释,并且它也全局适用于所有JSON响应,因此不仅限于该操作。在您的配置方法中添加:

JsConfig.IncludeTypeInfo = true;

伪客户端代码:

var result = client.get("/SomeKingOfResources/123");
var typeInformation = result.__type;