# v4.0.56 Release Notes

We've happy to announce several big ticket features in this release adding an exciting suite of functionality 
across the ServiceStack board!

## Introducing AutoQuery Data!

ServiceStack's [AutoQuery](https://github.com/ServiceStack/ServiceStack/wiki/Auto-Query) feature already 
provides the most productive way to create lightweight, high-performance data-driven Services which are 
able to naturally benefit from ServiceStack's wider rich, value-added ecosystem and thanks to OrmLite's 
typed RDBMS-agnostic API, AutoQuery has been used to create fully-queryable Services 
[for most major RDBMS's](https://github.com/ServiceStack/ServiceStack.OrmLite#8-flavours-of-ormlite-is-on-nuget).

Whilst AutoQuery is optimized around server-side SQL querying of Relational Databases, we also wanted to 
adopt its productive dev model and open it up to allow rich querying of other Data Sources 
as well - which we're happy to announce is now possible with AutoQuery Data! 

### Learn Once, Query Everywhere :)

AutoQuery Data is a new implementation that closely follows the dev model you're used to with AutoQuery 
where any experience gained in creating RDBMS AutoQuery Services previously are now also applicable to 
Querying alternative data sources as well where all features except for the RDBMS-specific 
[Joining Tables](https://github.com/ServiceStack/ServiceStack/wiki/Auto-Query#joining-tables) and 
[Raw SQL Filters](https://github.com/ServiceStack/ServiceStack/wiki/Auto-Query#raw-sql-filters) features
also have an equivalent in AutoQuery Data as well. 

Like AutoQuery you can declaratively create AutoQuery Data Services using just Request DTO's but instead of 
inheriting from `QueryBase<T>` you'd instead inherit from `QueryData<T>`, e.g:

```csharp
//AutoQuery RDBMS
public class QueryCustomers : QueryBase<Customer> {}

//AutoQuery Data - Multiple / Open Data Sources 
public class QueryCustomers : QueryData<Customer> {}
```

The API to call and consume both RDBMS AutoQuery and AutoQuery Data Services are indistinguishable to 
external clients where both are queried using the same 
[implicit](https://github.com/ServiceStack/ServiceStack/wiki/Auto-Query#implicit-conventions) and 
[explicit conventions](https://github.com/ServiceStack/ServiceStack/wiki/Auto-Query#explicit-conventions) 
and both return the same `QueryResponse<T>` Response DTO. 

### Use AutoQuery Viewer

A direct result of this means you can reuse [AutoQuery Viewer](https://github.com/ServiceStack/Admin) 
(announced in the previous release) to access a rich auto UI for querying all AutoQuery implementations 
together in the same UI, whether queries are served from an RDBMS or an alternative data source.

[![](https://raw.githubusercontent.com/ServiceStack/Admin/master/img/query-default-values.png)](https://github.com/ServiceStack/Admin)

## AutoQuery Data Sources

AutoQuery Data supports an Open Data provider model requiring an extra piece of configuration Services 
need to function - the Data Source that it will query. Data Sources are registered with the 
`AutoQueryDataFeature` plugin by calling using its fluent `AddDataSource()` API to register all Data Sources 
you want available to query. 

At launch there are 3 different data sources that are available - all of which are accessible as 
extension methods on the `QueryDataContext` parameter for easy discoverability:

```csharp
Plugins.Add(new AutoQueryDataFeature()
    .AddDataSource(ctx => ctx.MemorySource(...))
    .AddDataSource(ctx => ctx.ServiceSource(...))
    .AddDataSource(ctx => ctx.DynamoDBSource(...))
);
```

### Memory Data Source

The simplest data source we can query is an in-memory .NET collection registered with `ctx.MemorySource()`. 
But how the collection is populated remains up to you. The example below shows registering collections from 
multiple sources inc. **in-line code**, populated **from a CSV file** (utilizing ServiceStack's new 
CSV deserialization support) and populated **from a 3rd Party API** using 
[HTTP Utils](https://github.com/ServiceStack/ServiceStack/wiki/Http-Utils):

```csharp
//Declaration in code
var countries = new[] {
    new Country { ... },
    new Country { ... },
};

//From CSV File
List<Currency> currencies = File.ReadAllText("currencies.csv").FromCsv<List<Currency>>();

//From 3rd Party API
List<GithubRepo> repos = "https://api.github.com/orgs/ServiceStack/repos"
    .GetJsonFromUrl(req => req.UserAgent="AutoQuery").FromJson<List<GithubRepo>>();

//AutoQuery Data Plugin
Plugins.Add(new AutoQueryDataFeature { MaxLimit = 100 }
    .AddDataSource(ctx => ctx.MemorySource(countries))
    .AddDataSource(ctx => ctx.MemorySource(currencies))
    .AddDataSource(ctx => ctx.MemorySource(repos))
);
```

After data sources are registered, you can then create AutoQuery Data Services to query them:

```csharp
[Route("/countries")]
public class QueryCountries : QueryData<Country> {}

[Route("/currencies")]
public class QueryCurrencies : QueryData<Currency> {}

[Route("/repos")]
public class QueryGithubRepos : QueryData<GithubRepo> {}
```

With just the empty Request DTO's above they're now queryable like any other AutoQuery Service, e.g:

   - /countries?code=AU
   - /currencies.json?code=AUD
   - /repos.csv?watchers_count>=100&orderBy=-watchers_count,name&fields=name,homepage,language

### Cacheable Data Sources

The examples above provides a nice demonstration of querying static memory collections. But Data Sources 
offers even more flexibility where you're also able to query and cache dynamic .NET collections that 
are customizable per-request.

The registration below shows an example of this where results are dynamically fetched from **GitHub's API** 
and persisted in the **local in-memory cache** for **5 minutes** - throttling the number of requests made 
to the external 3rd Party API:

```csharp
.AddDataSource(ctx => ctx.MemorySource(() => 
    $"https://api.github.com/repos/ServiceStack/{ctx.Request.GetParam("repo")}/contributors"
      .GetJsonFromUrl(req => req.UserAgent="AutoQuery").FromJson<List<GithubContributor>>(),
    HostContext.LocalCache, 
    TimeSpan.FromMinutes(5)
));
```

We can now create an AutoQuery Data Service to query the above cached `GithubContributor` Memory Source:

```csharp
[Route("/contributors")]
public class QueryContributors : QueryData<GithubContributor>
{
    public string Repo { get; set; }
}
```

Thanks to the Typed Request DTO we also get an end-to-end Typed API for free which we can use to query 
the contributors result-set returned from GitHub's API. As an example we can view the 
**Top 20 Contributors** for the **ServiceStack** Project with:

```csharp
var top20Contributors = client.Get(new QueryContributors {
    Repo = "ServiceStack",
    OrderByDesc = "Contributions",
    Take = 20
});

top20Contributors.PrintDump(); // Pretty print results to Console
```

### Service Data Source

The next step in querying for even richer result-sets, whether you want to add custom validation, 
access multiple dependencies, construct complex queries or other custom business logic, you can use a 
**Service Source** instead which lets you call a Service and use its Response as the dynamic Data Source 
that you can apply Auto Querying logic on.

`ServiceSource` is very similar to `MemorySource` however instead of passing in the in-memory collection 
you want to query directly, you'll need to pass a **Request DTO** of the Service you want called instead.
The response of the Service is then further queried just as if its results were passed into a MemorySource 
directly.

We'll illustrate with a few examples how to register and use ServiceSources, explore some of their capabilities 
and provide some examples of when you may want to use them below. 

The `UserLogin` ServiceSouce shows you can just pass an empty Request DTO as-is to execute its Service. 
The `RockstarAlbum` and `GithubRepo` Service Sources are however leveraging the built-in
[Auto Mapping](https://github.com/ServiceStack/ServiceStack/wiki/Auto-mapping) to copy any matching 
properties from the AutoQuery Request DTO to the downstream `GetRockstarAlbums` and `GetGithubRepos` 
Request DTO's. Finally the responses for the `GithubRepo` Service is **cached for 5 minutes** so any 
subsequent matching requests end up querying the cached result set instead of re-executing the `GetGithubRepos` 
Service:

```csharp
Plugins.Add(new AutoQueryDataFeature { MaxLimit = 100 }
    .AddDataSource(ctx => ctx.ServiceSource<UserLogin>(new GetTodaysUserActivity())),
    .AddDataSource(ctx => ctx.ServiceSource<RockstarAlbum>(ctx.Dto.ConvertTo<GetRockstarAlbums>())),
    .AddDataSource(ctx => ctx.ServiceSource<GithubRepo>(ctx.Dto.ConvertTo<GetGithubRepos>(), 
        HostContext.Cache, TimeSpan.FromMinutes(5)));
);
```

The implementation of `GetTodaysUserActivity` Service uses an async OrmLite RDBMS call to get all User Logins 
within the last day, fetches the Live Activity data from Redis, then 
[merges the disconnected POCO result sets](https://github.com/ServiceStack/ServiceStack.OrmLite#merge-disconnected-poco-result-sets)
into the `UserLogin` POCO which it returns:

```csharp
[Route("/useractivity/today")]
public class QueryTodaysUserActivity : QueryData<User> {}

public async Task<List<UserLogin>> Any(GetTodaysUserActivity request)
{
    var logins = await Db.SelectAsync<UserLogin>(x => x.LastLogin >= DateTime.UtcNow.AddDays(-1));
    var activities = Redis.As<Activity>().GetAll();
    logins.Merge(activities);
    return logins;
}
```

The `GetRockstarAlbums` Service shows an example of a calling an existing ad hoc DB Service executing an 
arbitrary custom Query. It uses the Request DTO Auto-Mapping at the `ServiceSource` registration to 
first copy any matching properties from the initial `QueryRockstarAlbums` Request DTO to populate a new 
`GetRockstarAlbums` instance which is what's used to execute the Service with. 

In this way the `QueryRockstarAlbums` AutoQuery Service is essentially decorating the underlying 
`GetRockstarAlbums` Service giving it access to AutoQuery features where clients are able to apply 
further post-querying server logic to an existing Service implementation which now lets them filter, 
sort, select only a partial list of fields, include additional aggregate queries, etc.

```csharp
public class QueryRockstarAlbums : QueryData<RockstarAlbum> 
{
    public string Name { get; set; }
    public int[] IdBetween { get; set; }
}

public object Any(GetRockstarAlbums request)
{
    var q = Db.From<RockstarAlbum>();

    if (request.IdBetween != null)
        q.Where(x => x.Id >= request.IdBetween[0] && x.Id <= request.IdBetween[1]);

    if (request.Name != null)
        q.Where(x => x.Name == request.Name);

    return new GetRockstarAlbumsResponse { Results = Db.Select(q) };
}
```

One thing to notice is that ServiceSource still works whether the results are wrapped in a Response DTO 
instead of a naked `IEnumerable<RockstarAlbum>` collection. This is transparently supported as `ServiceSource` 
will use the first matching `IEnumerable<T>` property for Services that don't return a collection.

It should be noted that decorating an existing OrmLite Service is rarely necessary as in most cases you'll
be able to get by with just a simple AutoQuery RDBMS query as seen in the Service below which replaces 
the above 2 Services:

```csharp
public class QueryRockstarAlbums : QueryDb<RockstarAlbum> {}
```

The final `GetGithubRepos` ServiceSource example shows an example of a slightly more complex implementation
than a single 3rd Party API call where it adds custom validation logic and call different 3rd Party API 
Endpoints depending on user input:

```csharp
public class QueryGithubRepo : QueryData<GithubRepo> 
{
    public string User { get; set; }
    public string Organization { get; set; }
}

public object Get(GetGithubRepos request)
{
    if (request.User == null && request.Organization == null)
        throw new ArgumentNullException("User");

    var url = request.User != null
        ? "https://api.github.com/users/{0}/repos".Fmt(request.User)
        : "https://api.github.com/orgs/{0}/repos".Fmt(request.Organization);

    return url.GetJsonFromUrl(requestFilter:req => req.UserAgent = GetType().Name)
        .FromJson<List<GithubRepo>>();
}
```

A hidden feature ServiceSources are naturally able to take advantage of due to its behind-the-scenes usage 
of the new **ServiceGateway** (announced later) is that the exact code above could still function if the
`QueryGithubRepo` AutoQuery Data Service and underlying `GetGithubRepos` Service were moved to different
hosts :)

### Custom AutoQuery Data Implementation

Just like you can 
[Create a Custom implementation](https://github.com/ServiceStack/ServiceStack/wiki/Auto-Query#custom-autoquery-implementations)
in AutoQuery, you can do the same in AutoQuery Data by just defining an implementation for your AutoQuery 
Data Request DTO. But instead of `IAutoQueryDb` you'd reference the `IAutoQueryData` dependency to construct 
and execute your custom AutoQuery Data query.

When overriding the default implementation of an AutoQuery Data Service you also no longer need to register 
a Data Source as you can specify the Data Source in-line when calling `AutoQuery.CreateQuery()`.

For our custom AutoQuery Data implementation we'll look at creating a useful Service which reads the
daily CSV Request and Error Logs from the new `CsvRequestLogger` (announced later) and queries it by 
wrapping the POCO `RequestLogEntry` results into a `MemoryDataSource`:

```csharp
[Route("/query/requestlogs")]
[Route("/query/requestlogs/{Date}")]
public class QueryRequestLogs : QueryData<RequestLogEntry>
{
    public DateTime? Date { get; set; }
    public bool ViewErrors { get; set; }
}

public class CustomAutoQueryDataServices : Service
{
    public IAutoQueryData AutoQuery { get; set; }

    public object Any(QueryRequestLogs query)
    {
        var date = query.Date.GetValueOrDefault(DateTime.UtcNow);
        var logSuffix = query.ViewErrors ? "-errors" : "";
        var csvLogsFile = VirtualFileSources.GetFile("requestlogs/{0}-{1}/{0}-{1}-{2}{3}.csv".Fmt(
            date.Year.ToString("0000"),
            date.Month.ToString("00"),
            date.Day.ToString("00"),
            logSuffix));

        if (csvLogsFile == null)
            throw HttpError.NotFound("No logs found on " + date.ToShortDateString());

        var logs = csvLogsFile.ReadAllText().FromCsv<List<RequestLogEntry>>();

        var q = AutoQuery.CreateQuery(query, Request,
            db: new MemoryDataSource<RequestLogEntry>(logs, query, Request));

        return AutoQuery.Execute(query, q);
    }
}
```

This Service now lets you query the Request Logs of any given day, letting you filter, page and sort 
through the Request Logs of the day. While we're at it, let's also create multiple Custom AutoQuery 
Data implementations to act as canonical smart links for the above Service:

```csharp
[Route("/logs/today")]
public class TodayLogs : QueryData<RequestLogEntry> { }
[Route("/logs/today/errors")]
public class TodayErrorLogs : QueryData<RequestLogEntry> { }

[Route("/logs/yesterday")]
public class YesterdayLogs : QueryData<RequestLogEntry> { }
[Route("/logs/yesterday/errors")]
public class YesterdayErrorLogs : QueryData<RequestLogEntry> { }
```

The implementations of which just delegates to `QueryRequestLogs` with the selected Date and whether or 
not to show just the error logs:

```csharp
public object Any(TodayLogs request) =>
    Any(new QueryRequestLogs { Date = DateTime.UtcNow });

public object Any(TodayErrorLogs request) =>
    Any(new QueryRequestLogs { Date = DateTime.UtcNow, ViewErrors = true });

public object Any(YesterdayLogs request) =>
    Any(new QueryRequestLogs { Date = DateTime.UtcNow.AddDays(-1) });

public object Any(YesterdayErrorLogs request) =>
    Any(new QueryRequestLogs { Date = DateTime.UtcNow.AddDays(-1), ViewErrors = true });
```

And with no more effort we can jump back to `/ss_admin/` and use AutoQuery Viewer's nice UI to quickly 
inspect Todays and Yesterdays Request and Error Logs :)

![](https://raw.githubusercontent.com/ServiceStack/Assets/master/img/release-notes/autoqueryviewer-csv-logs.png)

## [DynamoDB Data Source!](https://github.com/ServiceStack/ServiceStack.Aws)

Probably the most exciting Data Source available is `DynamoDbSource` as it provides the most productive 
development experience for effortlessly creating rich, queryable and optimized Services for DynamoDB data stores! 

[![](https://raw.githubusercontent.com/ServiceStack/Assets/master/img/release-notes/dynamodb-banner.png)](https://github.com/ServiceStack/PocoDynamo)

DynamoDB is the near perfect solution if you're on AWS and in need of a managed NoSQL data storage solution 
that can achieve near-infinite scale whilst maintaining constant single-digit millisecond performance. 
The primary issue with DynamoDB however is working with it's unstructured schema and API's which is reflected 
in the official .NET DynamoDB client providing a flexible but low-level and cumbersome development experience 
to work with directly. Most of these shortcomings are resolved with our POCO-friendly 
[PocoDynamo](https://github.com/ServiceStack/PocoDynamo) client which provides an intuitive and idiomatic 
Typed .NET API that lets you reuse your DTO's and OrmLite POCO Data Models for persistence in DynamoDB.

Querying in DynamoDB is even more cumbersome, unlike an RDBMS which can process ad hoc queries on non-indexed 
fields with decent performance, every query in DynamoDB needs to be performed on an index defined ahead-of-time. 
Any queries not on an index needs to be sent as a Filter Expression and even more limiting is that queries 
can only be executed against rows containing the same hash id. If you need to query data spanning across 
multiple hash ids you either need to create a separate 
[Global Index](http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GSI.html) 
or perform a full 
[SCAN operation](http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/QueryAndScan.html#QueryAndScan.Scan) 
which is even slower than full table scans on an RDBMS as they need to be performed on all underlying sharded 
nodes which can quickly eat up your reserved provisioned throughput allotted to your DynamoDB table.

### Optimal DynamoDB Queries

With AutoQuery's `DynamoDbSource` a lot of these nuances are transparently handled where it will automatically 
create the most optimal DynamoDB Query based on the fields populated on the incoming AutoQuery Request DTO. 
E.g. it will perform a 
[DynamoDB Query](http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/QueryAndScan.html#QueryAndScan.Query)
when the **Hash** field is populated otherwise transparently falls back into a 
[Scan Operation](http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/QueryAndScan.html#QueryAndScan.Scan). 
Any conditions that query an Index field are added to the 
[Key Condition](http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/QueryAndScan.html#QueryAndScan.Query), 
starting first with the **Range Key** (if specified), otherwise uses any populated **Local Indexes** it can 
find before any of the remaining conditions are added to the 
[Filter Expression](http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/QueryAndScan.html#FilteringResults).

Transparently adopting the most optimal queries dramatically reduces development time as it lets you quickly
create, change and delete DynamoDB Services without regard for Indexes where it will often fallback to 
**SCAN** operations (performance of which is unnoticeable during development). Then once you're project is 
ready to deploy to production, go back and analyze all remaining queries your System relies on at the end 
then re-create tables with the appropriate indexes so that all App queries are efficiently querying an index.

> When needed you can specify `.DynamoDbSource<T>(allowScans:false)` to disable anyone from executing SCAN 
requests when deployed to production.

### Simple AutoQuery Data Example

To illustrate how to use AutoQuery with DynamoDB we'll walk through a simple example of querying Rockstars Albums. 
For this example we'll specify
[explicit conventions](https://github.com/ServiceStack/ServiceStack/wiki/Auto-Query#explicit-conventions)
so we can use ServiceStack's 
[typed .NET Service Clients](https://github.com/ServiceStack/ServiceStack/wiki/C%23-client) 
to show which fields we're going to query and also lets us call the Service with a convenient typed API:

```csharp
[Route("/rockstar-albums")]
public class QueryRockstarAlbums : QueryData<RockstarAlbum>
{
    public int? Id { get; set; }         // Primary Key | Range Key
    public int? RockstarId { get; set; } // Foreign key | Hash Key
    public string Name { get; set; }
    public string Genre { get; set; }
    public int[] IdBetween { get; set; }
}
```

Here we see that creating DynamoDB Queries is no different to any other AutoQuery Data Service, where the 
same definition is used irrespective if the data source was populated from a `MemorySource`, `ServiceSource` 
or `DynamoDbSource` and the only thing that would need to change to have it query an RDBMS instead is the 
`QueryDb<T>` base class.

The text in comments highlight that when the `RockstarAlbum` POCO is stored in an RDBMS 
[OrmLite](https://github.com/ServiceStack/ServiceStack.OrmLite) 
creates the table with the `Id` as the Primary Key and `RockstarId` as a Foreign Key to the `Rockstar` table. 
This is different in DynamoDB where 
[PocoDynamo](https://github.com/ServiceStack/PocoDynamo) behavior is to keep related records together so
they can be efficiently queried and will instead Create the `RockstarAlbum` DynamoDB Table with the 
`RockstarId` as the Hash Key and its unique `Id` as the Range Key.

#### Register DynamoDbSource

To use DynamoDB AutoQuery's you need to first configure 
[PocoDynamo](https://github.com/ServiceStack/PocoDynamo#download) 
which is just a matter of passing an an initialized `AmazonDynamoDBClient` and telling PocoDynamo which 
DynamoDB tables you intend to use:

```csharp
container.Register(c => new PocoDynamo(new AmazonDynamoDBClient(...))
    .RegisterTable<Rockstar>()
    .RegisterTable<RockstarAlbum>()
);
```

Then before using PocoDynamo, call `InitSchema()` to tell it to automatically go through and create all 
DynamoDB Tables that were registered but don't yet exist in DynamoDB: 

```csharp
var dynamo = container.Resolve<IPocoDynamo>();
dynamo.InitSchema();
```

So the first time `InitSchema()` is run it will create both `Rockstar` and `RockstarAlbum` tables but will 
no longer create any tables on any subsequent runs. After `InitSchema()` has completed we're assured that 
both `Rockstar` and `RockstarAlbum` tables exist so we can start using PocoDynamo's typed APIs to populate 
them with Data:

```csharp
dynamo.PutItems(new Rockstar[] { ... });
dynamo.PutItems(new RockstarAlbum[] { ... });
```

> Behind the scenes PocoDynamo efficiently creates the minimum number of 
[BatchWriteItem](http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_BatchWriteItem.html)
requests as necessary to store all Rockstar and RockstarAlbum's.

Now that we have data we can query we can register the AutoQuery Data plugin along with the `Rockstar` 
and `RockstarAlbum` DynamoDB Tables we want to be able to query: 

```csharp
Plugins.Add(new AutoQueryDataFeature { MaxLimit = 100 }
    .AddDataSource(ctx => ctx.DynamoDbSource<Rockstar>())
    .AddDataSource(ctx => ctx.DynamoDbSource<RockstarAlbum>())
);
```

#### RockstarAlbum POCO Table Definition

Where `RockstarAlbum` is just a simple POCO and can be used as-is throughout all of ServiceStack's libraries
inc. OrmLite, Redis, Caching Providers, Serializers, etc:

```csharp
public class RockstarAlbum
{
    [AutoIncrement]
    public int Id { get; set; }

    [References(typeof(Rockstar))]
    public int RockstarId { get; set; }

    [Index]
    public string Genre { get; set; }

    public string Name { get; set; }
}
```

PocoDynamo uses the same generic metadata attributes in **ServiceStack.Interfaces** as OrmLite. 

When this POCO is created in OrmLite it creates: 

 - A `RockstarAlbum` table with an `Id` auto incrementing **Primary Key**
 - The `RockstarId` as the **Foreign Key** for the `Rockstar` table 
 - Adds an **Index** on the `Genre` column. 

Whereas in DynamoDB, PocoDynamo creates: 

 - The `RockstarAlbum` table with the `Id` as an auto incrementing **Range Key**
 - The `RockstarId` as the **Hash Key** 
 - Creates a [Local Secondary Index](http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LSI.html) for the Genre attribute.

### Typed AutoQuery DynamoDB Queries

Since the properties we want to query are explicitly typed we can make use of ServiceStack's nice typed 
Service Client API's to call this Service and fetch Kurt Cobains **Grunge** Albums out of the first 5 recorded:

```csharp
var response = client.Get(new QueryRockstarAlbums { //QUERY 
    RockstarId = kurtCobainId, //Key Condition
    IdBetween = new[]{ 1, 5 }, //Key Condition
    Genre = "Grunge",          //Filter Condition
});

response.PrintDump(); // Pretty print results to Console
```

As illustrated in the comments, DynamoDB AutoQuery performs the most efficient DynamoDB Query required in 
order to satisfy this request where it will create a 
[Query Request](http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/QueryAndScan.html#QueryAndScan.Query)
with the `RockstarId` and `IdBetween` conditions added to the **Key Condition** and the remaining `Genre`
added as a **Filter Expression**.

If we instead wanted to fetch all of Kurt Cobains **Grunge** Albums where there was no longer a condition on 
the Album `Id` **Range Key**, i.e:

```csharp
var response = client.Get(new QueryRockstarAlbums { //QUERY
    RockstarId = kurtCobainId, //Key Condition
    Genre = "Grunge",          //Key Condition
});
```

It would instead create a **Query Request** configured to use the Genre **Local Secondary Index** and have
added both `RockstarId` Hash Key and index `Genre` to the **Key Condition**.

But if you instead wanted to view all Grunge Albums, i.e:

```csharp
var response = client.Get(new QueryRockstarAlbums { //SCAN
    Genre = "Grunge"            //Filter Condition
});
```

As no Hash Key was specified it would instead create a **SCAN Request** where as there's no index, it adds 
all conditions to the **Filter Expression**.

### AutoQuery DynamoDB Global Index Queries

For times when you need to perform an efficient **Query Request** across multiple hash keys you will need to 
create a [Global Secondary Index](http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GSI.html).
Luckily this is easy to do in PocoDynamo where you can define Global Indexes with a simple POCO class definition:

```csharp
public class RockstarAlbumGenreIndex : IGlobalIndex<RockstarAlbum>
{
    [HashKey]
    public string Genre { get; set; }

    [RangeKey]
    public int Id { get; set; }

    public string Name { get; set; }    // projected property
    public int RockstarId { get; set; } // projected property
}
```

Global Indexes can be thought of as "automatically synced tables" specified with a different Hash Key. 
Just like DynamoDB tables you can specify the **Hash Key** you want to globally query and create the Index 
on as well as a separate **Range Key** you want to be able to perform efficient **Key Condition** queries on. 
You'll also want to specify any properties you want returned when querying the Global Index so they'll be 
automatically projected and stored with the Global Index, ensuring fast access.

Then to have PocoDynamo create the Global Index it should be referenced on the table the Global Index is on:

```csharp
[References(typeof(RockstarAlbumGenreIndex))]
public class RockstarAlbum { ... }
```

When referenced, `InitSchema()` will create the `RockstarAlbumGenreIndex` Global Secondary Index when it
creates the `RockstarAlbum` DynamoDB Table.

With the Global Index created we can now query it just like we would any other DynamoDB AutoQuery but instead
of querying a table, we query the Index instead:

```csharp
public class QueryRockstarAlbumsGenreIndex : QueryData<RockstarAlbumGenreIndex>
{
    public string Genre { get; set; }     // Hash Key
    public int[] IdBetween { get; set; }  // Range Key
    public string Name { get; set; }
}
```

Once defined you can query it just like any other AutoQuery Service where you're now able to perform 
efficient queries by **Genre** across all Rockstar Album's:

```csharp
var response = client.Get(new QueryRockstarAlbumsGenreIndex //QUERY
{
    Genre = "Grunge",              //Key Condition
    IdBetween = new[] { 1, 1000 }, //Key Condition
});
```

### Custom POCO Result Mappings

A noticeable difference from querying a Global Index instead of the Table directly is that results are
returned in a different `RockstarAlbumGenreIndex` POCO. Luckily we can use AutoQuery's 
[Custom Results Feature](https://github.com/ServiceStack/ServiceStack/wiki/Auto-Query#returning-custom-results)
to map the properties back into the original table `RockstarAlbum` with:

```csharp
public class QueryRockstarAlbumsGenreIndex : QueryData<RockstarAlbumGenreIndex,RockstarAlbum> 
{ 
    public string Genre { get; set; }
    public int[] IdBetween { get; set; }
    public string Name { get; set; }
}
```

Now when we query the Index we get our results populated in `RockstarAlbum` DTO's instead:

```csharp
QueryResponse<RockstarAlbum> response = client.Get(new QueryRockstarAlbumsGenreIndex
{
    Genre = "Grunge",              //Key Condition
    IdBetween = new[] { 1, 1000 }, //Key Condition
});
```

### Caching AutoQuery Services

One of the many benefits of AutoQuery Services being just regular ServiceStack Services is that we get
access to ServiceStack's rich ecosystem of enhanced functionality around existing Services. An example added
in this release is ServiceStack's new HTTP Caching feature which lets you easily cache a Service with
the new `[CacheResponse]` attribute, letting you declaratively specify how long you want to cache identical 
requests for on the **Server** as well as a `MaxAge` option for instructing the **Client** how long they should
consider their local cache is valid for and any custom `Cache-Control` behavior you want them to have, e.g:

```csharp
[Route("/rockstar-albums")]
[CacheResponse(Duration = 60, MaxAge = 30, CacheControl = CacheControl.MustRevalidate)]
public class QueryRockstarAlbums : QueryData<RockstarAlbum>
{
    public int? Id { get; set; }         
    public int? RockstarId { get; set; }
    public string Genre { get; set; }
    public int[] IdBetween { get; set; }
}
```

So with just the above single Request DTO we've declaratively created a fully-queryable DynamoDB AutoQuery 
Service that transparently executes the most ideal DynamoDB queries for each request, has it's optimal 
representation efficiently cached on both Server and clients, whose Typed DTO can be reused as-is on the 
client to call Services with an end-to-end Typed API using any
[.NET Service Client](https://github.com/ServiceStack/ServiceStack/wiki/C%23-client), 
that's also available to external developers in a clean typed API, natively in their preferred language of 
choice, accessible with just a right-click menu integrated inside VS.NET, Xcode, Android Studio, IntelliJ 
and Eclipse - serving both PCL Xamarin.iOS/Android as well as native iOS and Android developers by just  
[Adding a ServiceStack Reference](https://github.com/ServiceStack/ServiceStack/wiki/Add-ServiceStack-Reference)
to the base URL of a remote ServiceStack Instance - all without needing to write any implementation!

### More Info

For more examples exploring different AutoQuery Data features checkout the
[AutoQuery Data Tests](https://github.com/ServiceStack/ServiceStack/blob/master/tests/ServiceStack.WebHost.Endpoints.Tests/AutoQueryDataTests.cs)
and [AutoQuery DynamoDB Tests](https://github.com/ServiceStack/ServiceStack/blob/master/tests/ServiceStack.WebHost.Endpoints.Tests/AutoQueryDataTests.Dynamo.cs)
that can be compared on a feature-by-feature basis against the existing
[AutoQuery Tests](https://github.com/ServiceStack/ServiceStack/blob/master/tests/ServiceStack.WebHost.Endpoints.Tests/AutoQueryTests.cs)
they were originally based on.

### AutoQuery Breaking Changes

As there are now 2 independent AutoQuery implementations we felt it necessary to rename the existing AutoQuery 
Types to establish a clear naming convention making it obvious which implementation the different Types are for. 
Types that are specific to the existing **RDBMS** AutoQuery now starts with `QueryDb*` whereas equivalent 
Types for AutoQuery **Data** start with `QueryData*`. The decorated example below shows an example of 
these differences:

```csharp
//AutoQuery RDBMS
[QueryDb(QueryTerm.Or)]
public class QueryCustomers : QueryDb<Customer> 
{
    [QueryDbField(Term = QueryTerm.Or, Operand = ">=", Field = "LastName")]
    public int? OrAgeOlderThan { get; set; }
}

public class AutoQueryRDBMSServices : Service
{
    public IAutoQueryDb AutoQuery { get; set; }
    ...
}

//AutoQuery Data - Multiple / Open Data Sources 
[QueryData(QueryTerm.Or)]
public class QueryCustomers : QueryData<Customer> 
{
    [QueryDataField(Term = QueryTerm.Or, Condition = ">=", Field = "LastName")]
    public int? OrAgeOlderThan { get; set; }
}

public class AutoQueryDataServices : Service
{
    public IAutoQueryData AutoQuery { get; set; }
    ...
}
```

For backwards compatibility we're continuing to support the most common usage for creating AutoQuery Services
that just inherit `QueryBase<T>`, but this is now deprecated in favor of `QueryDb<T>`. All other existing 
`[Query*]` attributes will need to be renamed to `[QueryDb*]` as seen above, likewise `IAutoQuery` is also 
deprecated and renamed to `IAutoQueryDb`. If in doubt please check any the deprecation message on types with 
any build errors as they'll indicate the name of the new Type it should be renamed to. 

We deeply regret any inconvenience these changes causes as we didn't foresee we'd extend AutoQuery Services to 
support multiple Data Sources beyond the RDBMS of which it was designed for. Introducing a clear naming 
convention now establishes a clear symmetry between both implementations which we expect to reduce a lot of
confusion in future.

### Other AutoQuery Features

#### Customizable Fields

AutoQuery's [Customizable Fields](https://github.com/ServiceStack/ServiceStack/wiki/Auto-Query#customizable-fields)
received some improvements where the fields list are now **case-insensitive**, e.g:

    ?fields=columnA,COLUMNB 

There's also now support for **wildcards** which let you quickly reference all fields on a table using the 
`table.*` format, e.g:

    ?fields=id,departmentid,department,employee.*

Which is a shorthand that expands to manually listing each field in the `Employee` table, useful for queries 
which joins multiple tables, e.g:

```csharp
[Route("/employees", "GET")]
public class QueryEmployees : QueryDb<Employee>,
    IJoin<Employee, EmployeeType>,
    IJoin<Employee, Department>,
    IJoin<Employee, Title> 
{
    //...
}
```

#### Exclude AutoQuery Collections from being initialized

The default configuration for all languages supported in
[Add ServiceStack Reference](https://github.com/ServiceStack/ServiceStack/wiki/Add-ServiceStack-Reference) 
is to 
[InitializeCollections](https://github.com/ServiceStack/ServiceStack/wiki/CSharp-Add-ServiceStack-Reference#initializecollections)
which allows for a nicer client API in which clients can assume Request DTO's have their collections 
initialized allowing them to use the shorthand collection initializer syntax, e.g:

```csharp
var response = client.Get(new SearchQuestions { 
    Tags = { "redis", "ormlite" }
});
```

A problem with this is that AutoQuery encourages having multiple collection properties, most of which will 
remain unused but would still have an empty collection initialized for all unused properties that are then 
emitted on the wire. To help with this we've made it easy to prevent collections from being emitted in 
AutoQuery DTO's by configuring the pre-registered `NativeTypesFeature` plugin below with:

```csharp
var nativeTypes = this.GetPlugin<NativeTypesFeature>();
nativeTypes.InitializeCollectionsForType = NativeTypesFeature.DontInitializeAutoQueryCollections;
```

## HTTP Caching

Another big ticket feature we expect to prove extremely valuable is the improved story around HTTP Caching
that transparently improves the behavior of existing `ToOptimized` Cached Responses, provides a typed API to 
to opt-in to **HTTP Client** features, introduces a simpler declarative API for enabling both
**Server and Client Caching** of Services and also includes Cache-aware clients that are able to improve the 
performance and robustness of all existing .NET Service Clients - functionality that's especially valuable to 
bandwidth-constrained Xamarin.iOS / Xamarin.Android clients offering improved performance and greater resilience.

The new caching functionality is encapsulated in the new `HttpCacheFeature` plugin that's pre-registered 
by default and can be removed to disable the new HTTP Caching behavior with:

```csharp
Plugins.RemoveAll(x => x is HttpCacheFeature);
```

### Server Caching

To explain the new HTTP Caching features we'll revisit the ServiceStack's previous caching support which
enables what we refer to as **Server Caching** where the response of a Service is cached in the registered
[Caching Provider](https://github.com/ServiceStack/ServiceStack/wiki/Caching)
by calling the `ToOptimizedResult*` API's which lets you programmatically construct the Cache Key and/or
how long the cache should be persisted for, e.g:

```csharp
public class OrdersService : Service
{
    public object Any(GetCustomers request)
    {
        //Good candidates: request.ToGetUrl() or base.Request.RawUrl
        var cacheKey = "unique_key_for_this_request";
        var expireCacheIn = TimeSpan.FromHours(1);

        return Request.ToOptimizedResultUsingCache(Cache, cacheKey, expireCacheIn, 
            () => {
                //Delegate executed only if item doesn't already exist in cache 
                //Any response DTO returned is cached on subsequent requests
            });
    }
}
```

As the name indicates this stores the most optimal representation of the Service Response in the registered 
`ICacheClient`, so for example if a client called the above API with `Accept: application/json` and 
`Accept-Encoding: deflate, gzip` HTTP Request Headers ServiceStack would store the deflated serialized JSON 
bytes in the Cache and on subsequent requests resulting in the same cache key would write the compressed 
deflated bytes directly to the Response OutputStream - saving both CPU and bandwidth.

#### More Optimal OptimizedResults

But there's an even more optimal result we could return instead: **Nothing** :) and save even more CPU and
bandwidth! Which is precisely what the
[HTTP Caching](https://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html) directives built into the HTTP spec
allow for. To enable it you'd need to return additional HTTP Headers to the client containing the necessary 
metadata they can use to determine when their locally cached responses are valid. Typically this is the 
[Last-Modified](https://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.3.1) 
date of when the Response/Resource was last modified or an 
[Entity Tag](https://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.3.2) containing an opaque string
the Server can use to determine whether the client has the most up-to-date response.

The most optimal cache validator we can use for existing `ToOptimizedResult*` API's is the **Last Modified**
date which is now being cached along with the response. An additional instruction we need to return to the 
client is the 
[Cache-Control](https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9) HTTP Response Header
which instructs the client what caching behavior to apply to the server response. As we want the new behavior 
to work transparently without introducing caching issues to existing Services, we've opted for a conservative:

    Cache-Control: max-age=0
    
Which tells the client to treat the server response as immediately stale and that it should send another
request to the Server for identical requests, but this time the client will append a 
[If-Modified-Since](https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.25) HTTP Request Header
which ServiceStack now automatically looks up to determine if the cache the client has is valid. 
If no newer cache for this request has been created since, ServiceStack returns a **304 NotModified** 
Response with an empty Request Body which tells the client it's safe to use their local cache instead.

#### Modify Cache-Control for OptimizedResults

You can change the `Cache-Control` Header returned for existing `ToOptimizedResult` responses by modifying
the pre-registered `HttpCacheFeature`, e.g:

```csharp
var cacheFeature = this.GetPlugin<HttpCacheFeature>();
cacheFeature.CacheControlForOptimizedResults = "max-age=3600, must-revalidate";
```

This tells the client that they can treat their locally cached server responses as **valid for 1hr**  
but **after 1hr** they must check back with the Server to determine if their cache is still valid.

### HTTP Client Caching

The Caching features above revolve around enhancing existing **Server Cached** responses with **HTTP Caching** 
features to further reduce latency and save CPU and bandwidth resources. In addition to **Server Caching** 
pure stand-alone **HTTP Caching** features (i.e. that don't cache server responses) are now available as 
first-class properties on `HttpResult`:

```csharp
// Only one Cache Validator below needs to be specified:
string ETag            // opaque string representing integrity of response
DateTime? LastModified // the last time the response was Modified

// Specify Client/Middleware Cache Behavior
TimeSpan? MaxAge          // How long cached response is considered valid
CacheControl CacheControl // More options to specify Cache-Control behavior:
enum CacheControl {
    None,
    Public,
    Private,
    MustRevalidate,
    NoCache,
    NoStore,
    NoTransform,
    ProxyRevalidate,
}

// Available, but rarely used
TimeSpan? Age      // Used by proxies to indicate how old cache is
DateTime? Expires  // Less preferred alternative to MaxAge
```

We'll walk through a couple of real-world examples to show how we can make use of these new properties
and explain the HTTP Caching behavior they enable. 

#### Using ETags

The minimum properties required for HTTP Caching is to specify either an `ETag` or `LastModified` 
Caching Validator. You can use any opaque string for the `ETag` that uniquely represents a version of the 
response that you can use to determine what version the client has, which could be an MD5 or SHA Hash of
the response but can also be a unique version string. E.g. Adding a `RowVersion` property to your OrmLite 
POCO Data Models turns on 
[OrmLite's Optimistic Concurrency](https://github.com/ServiceStack/ServiceStack.OrmLite#optimistic-concurrency)
feature where each time a record is modified it's automatically populated with a new version, these 
characteristics makes it ideal for use as an ETag which we can just return as a string:

```csharp
public object Any(GetCustomer request)
{
    var response = Db.SingleById<Customer>(request.Id);    
    return new HttpResult(response) {
        ETag = response.RowVersion.ToString(), 
    };
}
```

Whilst this is the minimum info required in your Services, the client also needs to know how long the 
cache is valid for as typically indicated by the `MaxAge` property. If it's omitted ServiceStack falls back 
to use the `HttpCacheFeature.DefaultMaxAge` of **10 minutes** which can be changed in your `AppHost` with:

```csharp
this.GetPlugin<HttpCacheFeature>().DefaultMaxAge = TimeSpan.FromHours(1);
```

So the HTTP Response Headers the client receives when calling this Service for the first time is something similar to:

    ETag: "42"
    Cache-Control: max-age=600

Which tells the client that they can use their local cache for identical requests issued within the next
10 minutes. After 10 minutes the cache is considered stale and the client will issue a new request to the 
server but this time it will include the **ETag** it has associated with the Response, i.e:

    If-None-Match: "42"

When this happens the Service is still executed as normal and if the Customer hasn't changed, the 
`HttpCacheFeature` will compare the `HttpResult.ETag` response with the clients **ETag** above and if they 
match ServiceStack will instead return a **304 NotModified** with an Empty Response Body to indicate to the 
client that it can continue to use their locally cached response.

So whilst using a `HttpResult` **doesn't cache** the response **on the Server** and save further resources 
used in executing the Service, it still benefits from allowing the client to use their local cache for 
**10 minutes** - eliminating server requests and yielding instant response times. Then after **10 minutes** 
the **304 NotModified** Response Status and **Empty Body** improves latency and saves the Server CPU and 
bandwidth resources it didn't have to use for serializing and writing the executed Services response it 
would have need to do if no Caching was enabled.

#### Using LastModified 

The alternative to using an `ETag` is to use the `Last-Modified` Caching Validator. When you're constructing 
a complex response you'll want to use the **most recent** Last Modified Date from all sources so that you
can determine that the cache is no longer valid when any of the sources have been updated.

If you also want to customize the clients **Cache-Control** behavior you can use the additional `HttpResult` 
properties, below is an example of doing both:

```csharp
public object Any(GetCustomerOrders request)
{
    var response = new GetCustomerOrdersResponse {
        Customer = Db.SingleById<Customer>(request.Id),
        Orders = Db.Select<Order>(x => x.CustomerId == request.Id),
    };

    var allDates = new List<DateTime>(response.Orders.Select(x => x.ModifiedDate)) {
        response.Customer.ModifiedDate,
    };

    return new HttpResult(response)
    {
        LastModified = allDates.OrderByDescending(x => x).First(),
        MaxAge = TimeSpan.FromSeconds(60),
        CacheControl = CacheControl.Public | CacheControl.MustRevalidate,
    };
}
```

Which returns the Last Modified Date of the `Customer` record or any of their `Orders` as well as the 
customized **Cache-Control** Header which together returns Response Headers similar to:

    Last-Modified: Fri, 19 April 2016 05:00:00 GMT
    Cache-Control: max-age=60, public, must-revalidate

Then after **60 seconds** have elapsed the client will re-issue a request but instead of sending a 
`If-None-Match` Request Header and **ETag**, instead sends `If-Modified-Since` and the **Last-Modified** date:

    If-Modified-Since: Fri, 19 April 2016 05:00:00 GMT

The resulting behavior is identical to that of the **ETag** above but instead compares the LastModified dates
instead of ETag strings for validity.

### Short-circuiting HTTP Cache Validation

A further optimization that can be added to the HTTP Cache workflow is using `IRequest.HasValidCache()`
to short-circuit the execution of a Service after you've processed enough information to determine either 
the `ETag` or `LastModified` for the response. 

For example if you had a Service that transcodes video on-the-fly, you can use `Request.HasValidCache()` to 
check whether the client already has the latest version of the video, if it does we can return a 
**304 NotModified** result directly, short-circuiting the Service and saving any resources in executing the 
remainder of the implementation, which in this case would **bypass reading and transcoding** the .mp4 video:

```csharp
public object Any(GetOggVideo request)
{
    var mp4Video = VirtualFileSources.GetFile($"/videos/{request.Id}.mp4");   
    if (mp4Video == null)
        throw HttpError.NotFound($"Video #{request.Id} does not exist");
    
    if (Request.HasValidCache(mp4Video.LastModified))
        return HttpResult.NotModified();
    
    var encodedOggBytes = EncodeToOggVideo(file.ReadAllBytes());
    return new HttpResult(encodedOggBytes, "video/ogg") 
    {
        LastModified = mp4Video.LastModified,
        MaxAge = TimeSpan.FromDays(1),
    };
}
```

### New [CacheResponse] Attribute

We've briefly had a look at the existing `ToOptimizedResult*` API's to create **Server Caches** in 
ServiceStack as well as using a customized `HttpResult` to take advantage of **HTTP Caching** Client features. 
To make it even easier to use both, we've combined them together in a new declarative `[CacheResponse]`
[Request Filter attribute](https://github.com/ServiceStack/ServiceStack/wiki/Filter-attributes) 
which as it's non-invasive and simple to add, we expect it to be the most popular option for adding caching 
to your Services in future.

As a normal [Request Filter Attribute](https://github.com/ServiceStack/ServiceStack/wiki/Filter-attributes)
it can be added at the top-level of your Service class in which case it will cache the response of 
**All** Service implementations for **60 seconds**, e.g:

```csharp
[CacheResponse(Duration = 60)]
public class CachedServices : Service 
{ 
    public object Any(GetCustomer request) { ... }
    
    public object Any(GetCustomerOrders request) { ... }
}
```

It can also be applied individually on a single Service implementation:

```csharp
[CacheResponse(Duration = 60)]
public object Any(GetCustomer request)
{
    return Db.SingleById<Customer>(request.Id);
}
```

Or on Request DTO's, as we saw earlier on the `QueryRockstarAlbums` AutoQuery DynamoDB Request DTO:

```csharp
[CacheResponse(Duration = 60)]
public class QueryRockstarAlbums : QueryData<RockstarAlbum> { ... }
```

However adding Request Filter Attributes **on Request DTO's** goes against our recommendation for keeping 
your DTO's in a separate implementation and dependency-free **ServiceModel.dll** as it would require a 
dependency on the non-PCL **ServiceStack.dll** which would prohibit being able to reuse your existing 
DTO .dll in PCL libraries, limiting their potential re-use.

You can still take advantage of the `[CacheResponse]` attribute on AutoQuery Services by defining
a custom implementation, at which point adding the `[CacheResponse]` attribute behaves as normal and 
applies caching to your Service implementations. E.g. you can enable caching for multiple AutoQuery 
Services with:

```csharp
[CacheResponse(Duration = 60)]
public class MyCachedAutoQueryServices : Service 
{
    public IAutoQueryData AutoQuery { get; set; }

    public object Any(QueryRockstars query) =>
        AutoQuery.Execute(query, AutoQuery.CreateQuery(query, Request));
    
    public object Any(QueryRockstarAlbums query) =>
        AutoQuery.Execute(query, AutoQuery.CreateQuery(query, Request));
}
```

#### Server Cached and HTTP Caching enabled responses

When only specifying a `Duration=60` ServiceStack only **caches the Server Response** so it behaves similar
to using the existing `ToOptimizedResult()` API, e.g:

```csharp
public object Any(GetCustomer request)
{
    return Request.ToOptimizedResultUsingCache(Cache, 
        Request.RawUrl, TimeSpan.FromSeconds(60), 
        () => Db.SingleById<Customer>(request.Id));
}
```

To also enable **HTTP Caching** features you'll need to opt-in by specifying an additional HTTP Caching directive. 
E.g. including a `MaxAge` instructs ServiceStack to apply **HTTP Caching** logic and return the appropriate headers:

```csharp
[CacheResponse(Duration=60, MaxAge=30)]
public object Any(GetCustomer request) => Db.SingleById<Customer>(request.Id);
```

Where subsequent identical requests from a **cache-aware client** will return their locally cached version 
within the first **30 seconds**, between **30-60 seconds** the client will re-validate the request with the 
Server who will return a **304 NotModified** Response with an **Empty Body**, after **60 seconds** the cache 
expires and the next request will **re-execute the Service** and populate the cache with a new response.

#### CacheResponse Properties

The Caching behavior of the `[CacheResponse]` attribute can be further customized using any of the 
additional properties below:

```csharp        
int Duration              // Cache expiry in seconds
int MaxAge                // MaxAge in seconds
CacheControl CacheControl // Customize Cache-Control HTTP Headers
bool VaryByUser           // Vary cache per user
string[] VaryByRoles      // Vary cache for users in these roles
bool LocalCache           // Use In Memory HostContext.LocalCache or HostContext.Cache
```

Using any of the other HTTP Cache properties will also trigger the HTTP Caching features. 
When a `MaxAge` isn't specified, i.e:

```csharp
[CacheResponse(Duration = 10, VaryByUser = true)]
public object Any(GetUserActivity request) { ... }
```

ServiceStack falls back to use the `HttpCacheFeature.DefaultMaxAge` which defaults to **10 minutes**, 
in addition to the `VaryByUser` flag will construct a unique cache key for each user and return an additional 
`Vary: Cookie` HTTP Response Header.

### Advanced CacheInfo Customization

One limitation of using a .NET Attribute to specify caching behavior is that we're limited to using 
.NET constant primitives prohibiting the use of allowing custom lambda's to capture custom behavior. 
This is also the reason why we need to use `int` for `Duration` and `MaxAge` instead of a more appropriate 
`TimeSpan`.

But we can still intercept the way the `[CacheResponse]` attribute works behind-the-scenes and programmatically 
enhance it with custom logic. 
[CacheResponseAttribute](https://github.com/ServiceStack/ServiceStack/blob/master/src/ServiceStack/CacheResponseAttribute.cs)
is just a wrapper around initializing a populated 
[CacheInfo](https://github.com/ServiceStack/ServiceStack/blob/master/src/ServiceStack/CacheInfo.cs) POCO
that it drops into the `IRequest.Items` dictionary where it's visible to your Service and any remaining Filters 
in ServiceStack's [Request Pipeline](https://github.com/ServiceStack/ServiceStack/wiki/Order-of-Operations). 
Essentially it's just doing this:

```csharp
req.Items[Keywords.CacheInfo] = new CacheInfo { ... };
```

The actual validation logic for processing the `CacheInfo` is encapsulated within the `HttpCacheFeature` 
Response Filter. This gives our Service a chance to modify it's behavior, e.g. in order to generically
handle all Service responses the `[CacheResponse]` attribute uses the `IRequest.RawUrl` 
(the URL minus the domain) for the base CacheKey. Whilst using a RawUrl is suitable in uniquely identifying 
most requests, if QueryString params were sent in a different case or in a different order it would generate 
a different url and multiple caches for essentially the same request. We can remedy this behavior by changing 
the base CacheKey used which is just a matter retrieving the populated the `CacheInfo` and change the 
`KeyBase` to use the predictable [Reverse Routing](https://github.com/ServiceStack/ServiceStack/wiki/Routing#reverse-routing)
`ToGetUrl()` API instead, e.g:

```csharp
[CacheResponse(Duration = 60)]
public object Get(MyRequest request)
{
    var cacheInfo = (CacheInfo)base.Request.GetItem(Keywords.CacheInfo);
    cacheInfo.KeyBase = request.ToGetUrl(); //custom cache key
    if (Request.HandleValidCache(cacheInfo))
        return null;
    ...

    return response;
}
```

`HandleValidCache()` is used to re-validate the client's request with the new Cache Key and if it's determined
the Client has a valid cache, will short-circuit the Service and return a **304 NotModified** Response.

## Cache-Aware Service Clients

We've now covered most of the **Server Caching** and **HTTP Caching** features in ServiceStack whose usage will
automatically benefit Websites as browsers have excellent support for HTTP Caching. But .NET Desktop Apps
or Xamarin.iOS and Xamarin.Android mobile clients wont see any of these benefits since none of the existing
Service Clients have support for **HTTP Caching**. 

To complete the story we've also developed a cache-aware `CachedServiceClient` that can be used to enhance 
all existing `HttpWebRequest` based Service Clients which manages its own local cache as instructed by the 
HTTP Caching directives, whilst the `CachedHttpClient` does the same for the HttpClient-based `JsonHttpClient`.

Both Cache-Aware clients implement the full 
[IServiceClient](https://github.com/ServiceStack/ServiceStack/blob/master/docs/pages/IServiceClient.md)
interface so they should be an easy drop-in enhancement for existing applications:

```csharp
IServiceClient client = new JsonServiceClient(baseUrl).WithCache(); 

//equivalent to:
IServiceClient client = new CachedServiceClient(new JsonServiceClient(baseUrl));
```

Likewise for `JsonHttpClient`:

```csharp
IServiceClient client = new JsonHttpClient(baseUrl).WithCache(); 

//equivalent to:
IServiceClient client = new CachedHttpClient(new JsonHttpClient(baseUrl));
```

As seen above they're essentially decorators over existing .NET Service Clients where they'll append the 
appropriate HTTP Request Headers and inspect the HTTP Responses of **GET** Requests that contain 
HTTP Caching directives. All other HTTP Methods are just delegated through to the underlying Service Client.

The Service Clients maintain cached responses in an internal dictionary which can also be injected and 
shared if your app uses multiple Service Clients. For example they could use the fast binary 
[MsgPack client](https://github.com/ServiceStack/ServiceStack/wiki/MessagePack-Format) 
for performance-sensitive queries or Services returning binary data and use a JSON client for everything else:

```csharp
var sharedCache = new ConcurrentDictionary<string, HttpCacheEntry>();

IServiceClient msgPackClient = new MsgPackServiceClient(baseUrl).WithCache(sharedCache);

IServiceClient jsonClient = new JsonHttpClient(baseUrl).WithCache(sharedCache);
```

### Improved Performance and Reliability

When caching is enabled on Services, the Cache-aware Service Clients can dramatically improve performance by
eliminating server requests entirely as well as reducing bandwidth for re-validated requests. They also 
offer an additional layer of resiliency as re-validated requests that result in Errors will transparently 
fallback to using pre-existing locally cached responses. For bandwidth-constrained environments like Mobile
Apps they can dramatically improve the User Experience and as they're available in all supported PCL 
client platforms - we recommend their use where HTTP Caching is enabled on the Server.  

### Community Resources on Caching

The new Caching support was developed in collaboration with members of the ServiceStack Community particularly
[@JezzSantos](https://twitter.com/JezzSantos) who was also developing his own ServiceStack Caching Solution 
in parallel which he recently 
[wrote about in comprehensive detail](http://www.mindkin.co.nz/blog/2016/1/5/caching-anyone) - a must read
if you want to learn more about HTTP Caching and explore alternative solutions for maintaining dependent 
caches within ServiceStack.

## Service Gateway

Another valuable capability added in this release that despite being trivial to implement on top of 
ServiceStack's existing message-based architecture, opens up exciting new possibilities for development 
of loosely-coupled
[Modularized Service Architectures](https://github.com/ServiceStack/ServiceStack/wiki/Modularizing-services).

The new [IServiceGateway](https://github.com/ServiceStack/ServiceStack/blob/master/src/ServiceStack.Interfaces/IServiceGateway.cs)
interfaces represent the minimal surface area required to support ServiceStack's different calling conventions 
in a formalized API that supports both Sync and Async Service Integrations:

```csharp
public interface IServiceGateway
{
    // Normal Request/Reply Services
    TResponse Send<TResponse>(object requestDto);

    // Auto Batched Request/Reply Requests
    List<TResponse> SendAll<TResponse>(IEnumerable<object> requestDtos);

    // OneWay Service
    void Publish(object requestDto);

    // Auto Batched OneWay Requests
    void PublishAll(IEnumerable<object> requestDtos);
}

// Equivalent Async API's
public interface IServiceGatewayAsync
{
    Task<TResponse> SendAsync<TResponse>(object requestDto, 
        CancellationToken token = default(CancellationToken));

    Task<List<TResponse>> SendAllAsync<TResponse>(IEnumerable<object> requestDtos, 
        CancellationToken token = default(CancellationToken));

    Task PublishAsync(object requestDto, 
        CancellationToken token = default(CancellationToken));

    Task PublishAllAsync(IEnumerable<object> requestDtos, 
        CancellationToken token = default(CancellationToken));
}
```

The minimum set of API's above requires the least burden for `IServiceGateway` implementers whilst the
[ServiceGatewayExtensions](https://github.com/ServiceStack/ServiceStack/blob/master/src/ServiceStack.Client/ServiceGatewayExtensions.cs)
overlays convenience API's common to all implementations providing the nicest API's possible for Request DTO's 
implementing the recommended `IReturn<T>` and `IReturnVoid` interface markers. The extension methods also 
provide fallback pseudo-async support for `IServiceGateway` implementations that also don't implement the
optional `IServiceGatewayAsync`, but will use native async implementations for those that do.

Naked Request DTO's without annotations are sent as a **POST** but alternative Verbs are also supported 
by annotating Request DTO's with 
[HTTP Verb Interface Markers](https://github.com/ServiceStack/ServiceStack/wiki/C%23-client#http-verb-interface-markers)
where Request DTO's containing `IGet`, `IPut`, etc. are sent using the typed Verb API, e.g:

```csharp
[Route("/customers/{Id}")]
public class GetCustomer : IReturn<Customer>, IGet
{
    public int Id { get; set ;}
}

var customer = client.Send(new GetCustomer { Id = 1 }); //GET /customers/1
//Equivalent to:
var customer = client.Get(new GetCustomer { Id = 1 });  
```

### Service Integration API's

To execute existing ServiceStack Services internally you can call `ExecuteRequest(requestDto)` which 
passes the Request DTO along with the current `IRequest` into the `ServiceController.Execute()` to execute. 
The alternative is to call `ResolveService<T>` to resolve an autowired instance of the Service that's 
injected with the current `IRequest` context letting you call methods on the Service instance directly.
Below is an example of using both API's:

```csharp
public object Any(GetCustomerOrders request)
{
    using (var orderService = base.ResolveService<OrderService>())
    {
        return new GetCustomerOrders {
            Customer = (Customer)base.ExecuteRequest(new GetCustomer { Id = request.Id }),
            Orders = orderService.Any(new QueryOrders { CustomerId = request.Id })
        };
    }
}
```

The recommended approach now is to instead use the `IServiceGateway` accessible from `base.Gateway` 
available in all Service, Razor Views, MVC ServiceStackController classes, etc. It works similar to
the `ExecuteRequest()` API (which it now replaces) where you can invoke a Service with just a populated 
Request DTO, but instead yields an ideal typed API for Request DTO's implementing the recommended `IReturn<T>`
or `IReturnVoid` markers:

```csharp
public object Any(GetCustomerOrders request)
{
    return new GetCustomerOrders {
        Customer = Gateway.Send(new GetCustomer { Id = request.Id }),
        Orders = Gateway.Send(new QueryOrders { CustomerId = request.Id })
    };
}
```

Or you can use the Async API if you prefer the non-blocking version:

```csharp
public async Task<GetCustomerOrdersResponse> Any(GetCustomerOrders request)
{
    return new GetCustomerOrdersResponse {
        Customer = await Gateway.SendAsync(new GetCustomer { Id = request.Id }),
        Orders = await Gateway.SendAsync(new QueryOrders { CustomerId = request.Id })
    };
}
```

The capability that sets the ServiceGateway apart (other than offering a nicer API to work with) 
is that this System could later have its **Customer** and **Order** Subsystems split out into different 
hosts and this exact Service implementation would continue to function as before, albeit a little slower due 
to the overhead of any introduced out-of-process communications.

The default implementation of `IServiceGateway` uses the 
[InProcessServiceGateway](https://github.com/ServiceStack/ServiceStack/blob/master/src/ServiceStack/InProcessServiceGateway.cs)
which delegates the Request DTO to the appropriate `ServiceController.Execute()` or 
`ServiceController.ExecuteAsync()` methods to execute the Service. One noticeable difference is that any 
Exceptions thrown by downstream Services are automatically converted into the same `WebServiceException` 
that clients would throw when calling the Service externally, this is so Exceptions are indistinguishable
whether it's calling an internal Service or an external one, which begins touching on the benefits of the 
Gateway... 

The ServiceGateway is the same interface whether you're calling an Internal Service on the Server or a 
remote Service from a client. It exposes an ideal message-based API that's
[optimal for remote Service Integrations](http://www.infoq.com/articles/interview-servicestack) 
that also supports 
[Auto Batched Requests](https://github.com/ServiceStack/ServiceStack/wiki/Auto-Batched-Requests) 
for combining multiple Service Calls into a single Request, minimizing latency when possible.

### Substitutable Service Gateways

These characteristics makes it easy to substitute and customize the behavior of the Gateway as visible in the
examples below. The easiest scenario to support is to redirect all Service Gateway calls to a remote 
ServiceStack instance which can be done by registering any .NET Service Client against the `IServiceGateway` 
interface, e.g:

```csharp
public override void Configure(Container container)
{
    container.Register<IServiceGateway>(c => new JsonServiceClient(baseUrl));
}
```

A more likely scenario you'd want to support is a mix where internal requests are executed in-process 
and external requests call their respective Service. If your system is split in two this becomes a simple
check to return the local InProcess Gateway for Requests which are defined in this ServiceStack instance
otherwise return a Service Client configured to the alternative host when not, e.g:

```csharp
public class CustomServiceGatewayFactory : ServiceGatewayFactoryBase
{
    public override IServiceGateway GetGateway(Type requestType)
    {
        var isLocal = HostContext.Metadata.RequestTypes.Contains(requestType);
        var gateway = isLocal
            ? (IServiceGateway)base.localGateway
            : new JsonServiceClient(alternativeBaseUrl);
        return gateway;
    }
}
```

For this we needed to implement the
[IServiceGatewayFactory](https://github.com/ServiceStack/ServiceStack/blob/master/src/ServiceStack.Interfaces/Web/IServiceGatewayFactory.cs)
so we can first capture the current `IRequest` that's needed in order to call the In Process Service Gateway with.
The convenience [ServiceGatewayFactoryBase](https://github.com/ServiceStack/ServiceStack/blob/master/src/ServiceStack/ServiceGatewayFactoryBase.cs)
abstracts the rest of the API away so you're only tasked with returning the appropriate Service Gateway for 
the specified Request DTO. 

Capturing the current `IRequest` makes the Gateway factory instance non-suitable to use as a singleton, 
so we'll need to register it with a `ReuseScope.None` scope so a new instance is resolved each time:

```csharp
public override void Configure(Container container)
{
    container.Register<IServiceGatewayFactory>(x => new CustomServiceGatewayFactory())
        .ReusedWithin(ReuseScope.None);
}
```

## Service Discovery Gateways

We're fortunate to have a vibrant community which quickly saw the value in this new capability where they 
were quick to jump in and contribute their own well-documented and supported value-added OSS solutions:

### [ServiceStack.Discovery.Consul](https://github.com/MacLeanElectrical/servicestack-discovery-consul)

The [ConsulFeature](https://github.com/MacLeanElectrical/servicestack-discovery-consul) plugin 
by [Scott Mackay](https://github.com/wwwlicious) leverages the hardened distributed Discovery Services and 
highly available features in [consul.io](https://www.consul.io/) to provide automatic registration and 
de-registration of ServiceStack Services on AppHost **StartUp** and **Dispose** that's available from:

    PM> Install-Package ServiceStack.Discovery.Consul

Without any additional effort beyond registering the `ConsulFeature` plugin and starting a new ServiceStack 
Instance it provides an auto-updating, self-maintaining and periodically checked registry of available Services:

```csharp
public override void Configure(Container container)
{
    SetConfig(new HostConfig {
        WebHostUrl = "http://api.acme.com:1234", // Externally resolvable BaseUrl
    });

    Plugins.Add(new ConsulFeature()); // Register the plugin, that's it!
}
```

![](https://raw.githubusercontent.com/ServiceStack/Assets/master/img/release-notes/ServiceRegistration.png)

Once registered, the Service Gateway works as you'd expect where internal requests are executed in process
and external requests queries the Consul registry to discover the appropriate and available Service to call:

```csharp
public class MyService : Service
{
    public void Any(RequestDTO dto)
    {
        // Gateway will automatically route external requests to correct service
        var internalCall = Gateway.Send(new InternalDTO { ... });
        var externalCall = Gateway.Send(new ExternalDTO { ... });
    }
}
```

![RequestDTO Service Discovery](https://raw.githubusercontent.com/MacLeanElectrical/servicestack-discovery-consul/master/assets/RequestDTOServiceDiscovery.png)

### [ServiceStack.Discovery.Redis](https://github.com/rsafier/ServiceStack.Discovery.Redis)

The [RedisServiceDiscoveryFeature](https://github.com/rsafier/ServiceStack.Discovery.Redis) by
[Richard Safier](https://github.com/rsafier) has similar goals to provide transparent service discovery 
but only requires access to Redis-backed datastore, but is otherwise just as easy to install:

    PM> Install-Package ServiceStack.Discovery.Redis

and Configure:

```csharp
public override void Configure(Container container)
{
    container.Register<IRedisClientsManager>(c => new RedisManagerPool(...));
        
    SetConfig(new HostConfig {
        WebHostUrl = "http://api.acme.com:1234"
    });

    Plugins.Add(new RedisServiceDiscoveryFeature());
}
```

Once registered, calling the same Gateway API's function the same way with internal requests executed
internally and external requests sent to the appropriate available node:

```csharp
public class MyService : Service
{
    public void Any(RequestDTO dto)
    {
        var internalCall = Gateway.Send(new InternalDTO { ... });
        var externalCall = Gateway.Send(new ExternalDTO { ... });

        try 
        {
            var unknown = Gateway.Send(new ExternalDTOWithNoActiveNodesOnline());
        }
        catch(RedisServiceDiscoveryGatewayException e) 
        {
           // If a DTO type is not local or resolvable by Redis discovery process 
           // a RedisServiceDiscoveryGatewayException will be thrown
        }
    }
}
```

Since all Redis Discovery data is stored in a redis instance the state of all available nodes can be viewed 
with any Redis GUI:

![](https://raw.githubusercontent.com/ServiceStack/Assets/master/img/release-notes/RedisDiscoveryScreenshot.png)

#### [ServiceStack.SimpleCloudControl](https://github.com/rsafier/ServiceStack.SimpleCloudControl)

In addition to this Redis Discovery Service Richard is also developing a series of ServiceStack plugins 
that enhances the functionality of ServiceStack.Discovery.Redis and provides cluster awareness to 
additional aspects of a ServiceStack AppHost's internal state.

### Designing for Microservices

Whether or not Systems 
[benefit overall from a fine-grained microservices architecture](http://blog.cleancoder.com/uncle-bob/2014/09/19/MicroServicesAndJars.html),
enough to justify the additional latency, management and infrastructure overhead it requires, we still see 
value in the development process of
[designing for Microservices](https://channel9.msdn.com/events/Build/2016/C918) where decoupling naturally 
isolated components into loosely-coupled subsystems has software-architecture benefits with overall complexity 
of an entire system being reduced into smaller, more manageable logical scopes which encapsulates their capabilities 
[behind small, re-usable, well-defined facades](http://stackoverflow.com/a/32940275/85785).

The ServiceGateway and its Services Discovery ecosystem together with ServiceStack's recommended use of 
impl-free reusable POCO DTO's and its ability to 
[modularize Service implementations across multiple projects](https://github.com/ServiceStack/ServiceStack/wiki/Modularizing-services)
naturally promote a microservices-ready architecture where Service interactions are loosely-coupled behind 
well-defined, reusable, coarse-grained messages. Designing systems in this way later allows the isolated
Service Implementation .dll to be extracted from the main System and wrapped into its own AppHost. Together 
with an agreed Service Discovery solution, allows you to spawn multiple instances of the new Service -
letting you scale, deploy and maintain it independently from the rest of the system.

## CSV Deserialization Support

The introduction of the new AutoQuery Data feature and it's `MemorySource` suddenly made full CSV support
a lot more appealing which caused CSV Deserialization support to be bumped up high on the priority list
where it's implementation is now complete. This now unlocks the ability to create fully-queryable Services 
over flat-file .csv's (or Excel spreadsheets exported to .csv) by just deserializing CSV into a List of 
POCO's and registering it with AutoQuery Data:

```csharp
var pocos = File.ReadAllText("path/to/data.csv").FromCsv<List<Poco>>();

//AutoQuery Data Plugin
Plugins.Add(new AutoQueryDataFeature()
    .AddDataSource(ctx => ctx.MemorySource(pocos)));

// AutoQuery DTO
[Route("/pocos")]
public class QueryPocos : QueryData<Poco> {}
```

### Super CSV Format

A noteworthy feature that sets ServiceStack's CSV support apart is that it's built on the compact and very fast
[JSV Format](https://github.com/ServiceStack/ServiceStack.Text/wiki/JSV-Format) which not only can 
deserialize a tabular flat file of scalar values at high-speed, it also supports deeply nested object graphs
which are encoded in JSV and escaped in a CSV field as normal. An example of this can be seen in a HTTP 
sample log fragment below where the HTTP Request Headers are a serialized from a `Dictionary<string,string>`:

    Id,HttpMethod,AbsoluteUri,Headers
    1,GET,http://localhost:55799,"{Connection:keep-alive,Accept:""text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"",Accept-Encoding:""gzip, deflate, sdch"",Accept-Language:""en-US,en;q=0.8"",Host:""localhost:55799"",User-Agent:""Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36"",Upgrade-Insecure-Requests:1}"

Being such a versatile file format opens up a lot of new possibilities, e.g. instead of capturing seed data
in code you could maintain them in plain-text .csv files and effortlessly load them on App Startup, e.g:

```csharp
using (var db = container.Resolve<IDbConnectionFactory>().Open())
{
    if (db.CreateTableIfNotExists<Country>()) //returns true if Table created
    {
        List<Country> countries = "~/App_Data/countries.csv".MapHostAbsolutePath()
            .ReadAllText().FromCsv<List<Country>>();
    
        db.InsertAll(countries);
    }
}
```

### All Services now accept CSV Content-Types

Another immediate benefit of CSV Deserialization is that now all Services can now process the CSV Content-Type. 
Being a tabular data format, CSV shines when it's processing a list of DTO's, one way to do that in 
ServiceStack is to have your Request DTO inherit `List<T>`:

```csharp
[Route("/pocos")]
public class Pocos : List<Poco>, IReturn<Pocos>
{
    public Pocos() {}
    public Pocos(IEnumerable<Poco> collection) : base(collection) {}
}
```

It also behaves the same way as CSV Serialization but in reverse where if your Request DTO is annotated 
with either `[DataContract]` or the more explicit `[Csv(CsvBehavior.FirstEnumerable)]` it will automatically 
deserialize the CSV into the first `IEnumerable` property, so these 2 Request DTO's are equivalent to above:

```csharp
[Route("/pocos")]
[DataContract]
public class Pocos : IReturn<Pocos>
{
    [DataMember]
    public List<Poco> Items { get; set; }
}

[Route("/pocos")]
[Csv(CsvBehavior.FirstEnumerable)]
public class Pocos : IReturn<Pocos>
{
    public List<Poco> Items { get; set; }
}
```

In addition to the above flexible options for defining CSV-friendly Services, there's also a few different 
options for sending CSV Requests to the above Services. You can use the new CSV `PostCsvToUrl()` extension 
methods added to [HTTP Utils](https://github.com/ServiceStack/ServiceStack/wiki/Http-Utils):

```csharp
string csvText = File.ReadAllText("pocos.csv");

//Send CSV Text
List<Poco> response = "http://example.org/pocos"
    .PostCsvToUrl(csvText)
    .FromCsv<List<Poco>>();
    
//Send POCO DTO's
List<Poco> dtos = csvText.FromCsv<List<Poco>>();
List<Poco> response = "http://example.org/pocos"
    .PostCsvToUrl(dtos)
    .FromCsv<List<Poco>>();    
```

Alternatively you can use the `CsvServiceClient` which has the nice Typed API's you'd expect from a 
Service Client:

```csharp
var client = new CsvServiceClient(baseUrl);

Pocos response = client.Post(new Pocos(dtos));
```

### Ideal for Auto Batched Requests

The `CsvServiceClient` by virtue of being configured to use a well-defined Tabular data format is perfect 
for sending 
[Auto-Batched Requests](https://github.com/ServiceStack/ServiceStack/wiki/Auto-Batched-Requests) 
which by definition send a batch of POCO's making the CSV format the most compact text format to send them with:

```csharp
var requests = new[]
{
    new Request { ... },
    new Request { ... },
    new Request { ... },
};

var responses = client.SendAll(requests);
```

### CSV Request Logger

Flipping the switch on CSV Deserialization has opened up the potential for a lot more useful features.
One of the areas we thought to be particularly valuable is being able to store daily Request Logs in a 
plain-text structured format, that way they could be immediately inspectable with a text editor or for even 
better inspection, opened in a spreadsheet and benefit from its filterable, movable, resizable and 
sortable columns.

To enable CSV Request Logging you just need to register the `RequestLogsFeature` and configure it to use the
[CsvRequestLogger](https://github.com/ServiceStack/ServiceStack/blob/master/src/ServiceStack/CsvRequestLogger.cs):

```csharp
Plugins.Add(new RequestLogsFeature {
    RequestLogger = new CsvRequestLogger(),
});
```

This will register the CSV Request logger with the following overridable defaults:

```csharp
Plugins.Add(new RequestLogsFeature {
    RequestLogger = new CsvRequestLogger(
        files = new FileSystemVirtualPathProvider(this, Config.WebHostPhysicalPath),
        requestLogsPattern = "requestlogs/{year}-{month}/{year}-{month}-{day}.csv",
        errorLogsPattern = "requestlogs/{year}-{month}/{year}-{month}-{day}-errors.csv"
        appendEvery = TimeSpan.FromSeconds(1)
    ),
});
```

Where Request Logs are flushed every **1 second** using a background Timer to a daily log maintained in
the logical date format structure above. As it would be useful to be able to inspect any errors in isolation, 
errors are also written to a separate `YYYY-MM-DD-errors.csv` format, in addition to the main Request logs.

## [Virtual FileSystem](https://github.com/ServiceStack/ServiceStack/wiki/Virtual-file-system)

To efficiently support Appending to existing files as needed by the `CsvRequestLogger` we've added new 
`AppendFile` API's and implementations for Memory and FileSystem Virtual File Providers:

```csharp
interface IVirtualFiles
{
    void AppendFile(string filePath, string textContents);
    void AppendFile(string filePath, Stream stream);
}
```

## [OrmLite](https://github.com/ServiceStack/ServiceStack.OrmLite)

### Updating existing values

The new `UpdateAdd` API's contributed by [Luis Madaleno](https://github.com/madaleno) provides several 
Typed API's for updating existing values:

```csharp
//Increase everyone's Score by 3 points
db.UpdateAdd(new Person { Score = 3 }, fields: x => x.Score); 

//Remove 5 points from Jackson Score
db.UpdateAdd(new Person { Score = -5 }, x => x.Score, x => where: x.LastName == "Jackson");

//Graduate everyone and increase everyone's Score by 2 points 
var q = db.From<Person>().Update(x => new { x.Points, x.Graduated });
db.UpdateAdd(new Person { Points = 2, Graduated = true }, q);

//Add 10 points to Michael's score
var q = db.From<Person>()
    .Where(x => x.FirstName == "Michael")
    .Update(x => x.Points);
db.UpdateAdd(new Person { Points = 10 }, q);
```

> Note: Any non-numeric values in an `UpdateAdd` statement (e.g. strings) are replaced as normal.

### BelongsTo Attribute

The `[BelongTo]` attribute can be used for specifying how Custom POCO results are mapped when the resultset 
is ambiguous, e.g:

```csharp
class A { 
    public int Id { get; set; }
}
class B {
    public int Id { get; set; }
    public int AId { get; set; }
}
class C {
    public int Id { get; set; }
    public int BId { get; set; }
}
class Combined {
    public int Id { get; set; }
    [BelongTo(typeof(B))]
    public int BId { get; set; }
}

var q = db.From<A>()
    .Join<B>()
    .LeftJoin<B,C>();

var results = db.Select<Combined>(q); //Combined.BId = B.Id
```

### Deprecating Legacy OrmLite API's

In order to gracefully clean up OrmLite's API Surface area and separate the modern recommended API's 
from the Legacy ones we've deprecated the Legacy API's which we plan to move into a separate
`ServiceStack.OrmLite.Legacy` namespace. Once moved, any use of Legacy API's will require including 
the additional namespace below:

```
using ServiceStack.OrmLite.Legacy;
```

The API's that have been deprecated are those with `*Fmt` suffix using in-line escaped string and the 
old-style C# `string.Format()` syntax for familiarity, e.g:

```csharp
var tracks = db.SelectFmt<Track>("Artist = {0} AND Album = {1}", 
  "Nirvana", 
  "Nevermind");
```

Instead we recommend the use of Typed APIs: 

```csharp
var tracks = db.Select<Track>(x => x.Artist == "Nirvana" && x.Album == "Nevermind");
```

Or when needed, Custom SQL API's that use `@parameter` names initialized with anonymous objects:

```csharp
var tracks = db.Select<Track>("Artist = @artist AND Album = @album", 
    new { artist = "Nirvana", album = "Nevermind" });

var tracks = db.SqlList<Track>(
    "SELECT * FROM Track WHERE Artist = @artist AND Album = @album",
    new { artist = "Nirvana", album = "Nevermind" });
```

As they both execute parameterized statements behind-the-scenes.

The other set of API's that have been tagged to move out of the primary `ServiceStack.OrmLite` and reduce
ambiguity of the existing API surface area are those that inject an `SqlExpression<T>`, e.g:

```csharp
var tracks = db.Select<Track>(q => 
    q.Where(x => x.Artist == "Nirvana" && x.Album == "Nevermind"));
```

These overloaded API's would often confuse IDE intellisense which were unsure whether to provide 
intelli-sense for `Track` or `SqlExpression<Track>` members. In future only POCO Data Models will be 
injected so the above API's should instead be changed to create and pass in an `SqlExpression<Track>` 
using `db.From<T>`, e.g:

```csharp
var tracks = db.Select(db.From<Track>() 
    .Where(x => x.Artist == "Nirvana" && x.Album == "Nevermind"));
```

## [PocoDynamo](https://github.com/ServiceStack/PocoDynamo)

Support for DynamoDB's [UpdateItem](http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateItem.html)
to modify an existing Item Attribute Value is now available. 

The simplest usage is to pass in a partially populated POCO where any Hash or Range Keys are added to the 
Key Condition and any non-default values are replaced. E.g the query below updates the Customer's Age to **42**:

```csharp
db.UpdateItemNonDefaults(new Customer { Id = customer.Id, Age = 42 });
```

DynamoDB's UpdateItem supports 3 different operation types: 

 - `PUT` to replace an Attribute Value
 - `ADD` to add to an existing Attribute Value
 - `DELETE` to delete the specified Attributes

Examples of all 3 are contained in the examples below which changes the Customer's `Nationality` to 
**Australian**, reduces their `Age` by **1** and deletes their `Name` and `Orders`:

```csharp
db.UpdateItem(customer.Id, 
    put: () => new Customer {
        Nationality = "Australian"
    },
    add: () => new Customer {
        Age = -1
    },
    delete: x => new { x.Name, x.Orders });
```

The same Typed API above is also available in the more flexible and untyped form below:

```csharp
db.UpdateItem<Customer>(new DynamoUpdateItem
{
    Hash = customer.Id,
    Put = new Dictionary<string, object>
    {
        { "Nationality", "Australian" },
    },
    Add = new Dictionary<string, object>
    {
        { "Age", -1 }
    },
    Delete = new[] { "Name", "Orders" },
});
```

## [ServiceStack.Redis](https://github.com/ServiceStack/ServiceStack.Redis)

More robust Exception handling of Sentinel Errors were added and now reconnections that occur in the 
middle of processing a command are gracefully retried and executed.

New API's were added to remove multiple values from a Sorted Set:

```csharp
interface IRedisClient {
    long RemoveItemsFromSortedSet(string setId, List<string> values);
} 

interface IRedisNativeClient {
    long ZRem(string setId, byte[][] values);
}
```

## [ServiceStackIDEA](https://github.com/ServiceStack/ServiceStack.Java)

The ServiceStack IDEA Android Studio plugin was updated to support 
[Android Studio 2.0](http://android-developers.blogspot.com/2016/04/android-studio-2-0.html).

## Community 

### [ServiceStack.EventStore](https://github.com/MacLeanElectrical/servicestack-eventstore)

The ServiceStack community has been very active in the last month with the developers over at 
[MacLean Electrical](http://www.maclean-electrical.com/) in addition to the Consul Discovery Plugin
having also released their 
[CQRS and event-sourced system plugin for ServiceStack](https://github.com/MacLeanElectrical/servicestack-eventstore) 
using [GetEventStore](https://geteventstore.com/):

    PM> Install-Package ServiceStack.EventStore

#### [ServiceStack.SimpleCloudControl](https://github.com/rsafier/ServiceStack.SimpleCloudControl)

Building on capabilities from his [ServiceStack.Discovery.Redis](https://github.com/rsafier/ServiceStack.Discovery.Redis)
Service [Richard Safier](https://github.com/rsafier) is developing a collection of useful plugins which add
enhanced introspection of the state, status and health of a cluster of ServiceStack instances. 
The available plugins in development include:

 - SimpleCloudControlFeature 
 - SimpleMQControlFeature
 - SimpleHybridCacheFeature 
 - SimpleCloudConfig 
 - SimpleCloudControlAdminFeature 

### [ServiceStackWithQuartz](https://github.com/CodeRevver/ServiceStackWithQuartz)

[Michael Clark](https://github.com/CodeRevver) has created a Plugin that allows an easy registration of 
all Quartz Jobs within ServiceStack's Funq container. This allows for dependency injection within any 
Quartz Job. Get Started with:

    PM> Install-Package ServiceStack.Funq.Quartz

Also checkout Michael's [Introductory Post](http://michaelclark.tech/2016/04/16/creating-a-servicestack-windows-service-that-uses-quartz/)
for more details.

### [Caching Anyone?](http://www.mindkin.co.nz/blog/2016/1/5/caching-anyone)

If you missed the link to [Jezz Santos](https://twitter.com/JezzSantos) comprehensive post on 
[HTTP Caching within ServiceStack](http://www.mindkin.co.nz/blog/2016/1/5/caching-anyone) from earlier, it's
one to checkout when you can set aside time for a long, good read.

## Other Features

- Changed `ServiceStack.Interfaces` to **Profile 328** adding support **Windows Phone 8.1**
- New `IHasStatusDescription` can be added on **Exceptions** to customize their `StatusDescription`
- New `IHasErrorCode` can be used to customize the `ErrorCode` used, instead of its Exception Type
- New `AppHost.OnLogError` can be used to override and suppress service error logging

# [v4.0.54 Release Notes](https://github.com/ServiceStack/ServiceStack/blob/master/docs/2016/v4.0.54.md)
