mat mat -4 years ago 103
ASP.NET (C#) Question

Using caching with a strongly typed service implementation in ServiceStack

I have my service definitions, which use strongly typed return DTOs via the IReturn interface

[Route ("/items/{id}", "GET")]
public class FindItems : IReturn<FindItemResponse>
{
public int Id { get; set; }
}

public class FindItemResponse { ... }


I also use that type with my service's implementation

public FindItemResponse Get (FindItems request)
{
...
}


This worked very well, until I tried to use ServiceStack's caching abilities. According to the documentation, one should use the
Request.ToOptimizedResultUsingCache? method, which returns object and not FindItemResponse. I checked the actual return type, sometimes its a JSON string, sometimes its a
ServiceStack.CompressedResult`, so no chance to manually convert it.

How is caching supposed to be done in ServiceStack, when you use a strongly typed response (as is recommended by @mythz)?

Answer Source

ToOptimizedResultUsingCache returns a CompressedResult on subsequent calls because it's returning the cached compressed bytes of the format (e.g. json) being requested.

This should be a transparent implementation detail for your clients which just receive a cached version of your Service. When using ToOptimizedResult* APIs your Service needs to be able to return a Cached response so you'll need to change the return type to object, e.g:

public object Get(FindItems request)
{ 
    return Request.ToOptimizedResultUsingCache(base.Cache,cacheKey,()=> 
    {
        return new FindItemResponse { ... }
    });        
}

Changing from an object to ResponseDto return Type is functionally equivalent and has no behavioral differences.

Since it has no effect my Services almost always have an object return Type unless I need to call it internally from other Services using base.ResolveService<T>, it's more important to specify the Response Type in the IReturn<T> interface marker, e.g:

public class FindItems : IReturn<FindItemResponse> {}

Which will enable the succinct typed APIs that .NET clients will be able to take advantage of.

An alternative to using ToOptimizedResult* APIs is to use the newer [CacheResponse] Attribute which will let your Services return a Typed Response DTO, e.g:

[CacheResponse(Duration = 60)]
public FindItemResponse Get(FindItems request)
{ 
    return new FindItemResponse { ... }
}

Where for subsequent calls will return the cached response instead of calling your Service.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download