How would you implement a partial request and response, for example, apt youtube, using ServiceStack?

The Youtube API has the ability to request a "partial feed" .

This allows the application developer to adapt the size and structure of the returned data, indicating which "fields" should be returned.

i.e. GET api/person/1?fields=(id,email)will return a DTO containing only the fields idand email, and not the entire user response.

How do you try to use this with ServiceStack? Is there a way to associate a callback with a serializer to control which properties to include in the response object?

+5
source share
4 answers

servicestack , . , , , - , , , , , , servicestack , .

+1

API, JSON.

() "":

  • FieldSelector, , , FieldSelection, ;
  • FieldsSelection, FieldSelector.

, , AFAIK, (de) / URL- ServiceStack. ToString (serializer) , ().

DTO, JSON:

FieldsSelection Fields { get; set; }

ServiceRunner<T>.OnAfterExecute DTO JSON, ServiceStack.Text 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 DTO, foo), .

+1

Look at the properties of ServiceStack.Text.JsConfig , they have all the hooks and settings that support ServiceStack text serializers. In particular, hooks that allow you to customize deserialization are as follows:

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

We were able to implement the specified filtering by adding a custom service runner and using some reflection in it to build ExpandoObjectwith the required field set by the DTO answer. See this for more information on service visitors.

0
source

All Articles