你将如何实现部分请求&响应,像youtube api,使用ServiceStack?

时间:2013-02-08 03:10:32

标签: servicestack

在Youtube API中,可以请求"partial feed"

这允许应用程序开发人员通过指定要返回的“字段”来定制返回的数据的大小和结构。

即。 GET api/person/1?fields=(id,email)会返回仅包含idemail字段的DTO,而不是整个人的回复。

您如何使用ServiceStack尝试此操作?是否有某种方法可以将回调附加到序列化程序以控制要包含在响应对象中的属性?

4 个答案:

答案 0 :(得分:1)

根据我的经验,servicestack只返回实际拥有数据的字段。如果我的经验是正确的,那么您需要做的就是找出构建请求的最佳方法,以便它要求返回特定数据,这样您只需要使用请求的数据填充响应,因此servicestack只会返回

答案 1 :(得分:1)

我为只返回JSON的API实现了这个。

首先,我创建了两个结构来(de)序列化和解释"字段"查询参数递归语法:

  • FieldSelector,用于指定括号内的字段及其子FieldSelection;
  • FieldsSelection,这是逗号分隔的FieldSelector
  • 列表

我使用了结构而不是类,因为在AFAIK中,您无法覆盖ServiceStack中的URL的(de)序列化。使用结构,您可以通过覆盖ToString(序列化程序)并提供一个接受字符串作为参数(反序列化程序)的构造函数来完成。

然后在每个返回JSON的请求DTO中包含此内容:

FieldsSelection Fields { get; set; }

在自定义ServiceRunner<T>.OnAfterExecute上,您将响应DTO序列化为JSON,使用ServiceStack.Text&#39; s JsonObject对其进行解析,并使用以下方法递归应用字段选择:

private static JsonObject Apply(this JsonObject json, FieldsSelection fieldMask)
{
  IEnumerable<string> keysToRemove = json.Keys.ToList().Except(fieldMask.Keys);

  foreach (var key in keysToRemove)
    json.Remove(key);

  foreach (var selector in fieldMask.Selectors.Values.Where(s => s.HasSubFieldsSelection))
  {
    var field = json[selector.Field];
    if (field == null)
      continue;

    switch (field[0])
    {
      case '{':
        json[selector.Field] = Apply(json.Object(selector.Field), selector.SubFieldsSelection).ToJson();
        break;
      case '[':
        var itensArray = json.ArrayObjects(selector.Field);
        for (int i = 0; i < itensArray.Count; i++)
          itensArray[i] = Apply(itensArray[i], selector.SubFieldsSelection);
        json[selector.Field] = itensArray.ToJson();
        break;
      default:
        throw new ArgumentException("Selection incompatible with object structure");
    }
  }

  return json;
}

然后将结果作为回复DTO返回。我还实现了负字段选择器(fields=-foo选择除foo之外的所有DTO字段),但是你明白了。

答案 2 :(得分:0)

查看ServiceStack.Text.JsConfig属性,它们具有ServiceStack文本序列化程序支持的所有钩子和自定义。特别是允许自定义反序列化的钩子是:

JsConfig<T>.DeserializeFn 
JsConfig<T>.RawDeSerializeFn 
JsConfig<T>.OnDeserializedFn

答案 3 :(得分:0)

我们能够通过添加自定义服务运行程序并使用其中的一些反射来实现所述过滤,以使用响应DTO设置的必填字段构建ExpandoObject。有关服务运行者的详细信息,请参阅this