Versioning Protocol of Astoria II

In my previous post on the protocol versioning scheme for Astoria, I've explained the two HTTP headers DataServiceVersion and MaxDataServiceVersion. These headers are used by the server and client library to determine how and what to communicate with each other. This mechanism is defined by the Astoria Protocol and our library's implementation does not require any user interactions. There is no public APIs to give users direct control of mechanism either. In fact, in the most common scenario where the server and the client versions match, one can simply ignore the existence of version control. However, if you ever need to setup a data service where the server and the consumer are built from two different versions of Astoria, you'll likely want to know what is expected to work and what is not.

With the release of CTP2, we have introduced a couple of new features on the server. In the table below I'll list these features and their behavior when it comes to cross-version calls. In the table, minimum requesting DataServiceVersion means the client must send a DSV header that's greater than or equal to this value, and the response DSV means the server will response with this version (which also means the MDSV header sent by the client must be less than or equal to this value).

Feature

Call Uri

Minimum Requesting DataServiceVersion

Response DataServiceVersion

Friendly Feeds

Any Entity With EPM mapping and KeepInContent set to false

1.0

2.0(ATOM) / 1.0(JSON)

 

Any Entity With EPM mapping and KeepInContent set to true

1.0

1.0

Server Driven Paging

Any EntitySets that are paged and the number of requested entities are greater than the page size

1.0 (First page) / 2.0 (Subsequent pages with $skipToken)

2.0

 

Any EntitySets that are paged and the number of requested entities are less than the page size

1.0

1.0

Row Count

/EntitySet?$inlinecount=allpages

2.0

2.0

 

/EntitySet/$count

2.0

2.0

Blob

Accessing media links

1.0

1.0

Projections

/EntitySet?$select=propertyList

2.0

1.0

The rule of thumb here is we require the requesting DSV to be 2.0 for all new URI constructs ($inlinecount, $count, $skipToken, $select), and the response DSV will be 2.0 if the content is incompatible with V1 response. For example, for Server Driven Paging, when the server truncates the result set, we will bump the response DSV to 2.0, because V1.0 client will ignore the continuation token and thus unable to receive the full results.

The Max Protocol Version configuration

For folks out there wanting to use V2 service and want their service to be V1 protocol compliant, you can "turn off" the features that may require a DSV of 2.0 by setting the MaxProtocolVersion configuration*. This setting is available only during service initialization:

public static void InitializeService(DataServiceConfiguration config)
{
    config.SetEntitySetAccessRule("*", EntitySetRights.All);
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V1;
}  

You can think of this as the service-side enforced "MaxDataServiceVersion" header. When this is set, any request that requires a DSV greater than 1.0 will fail even if the proper headers are present. The error message you get in this case is "The response requires that version 2 of the protocol be used, but the MaxProtocolVersion of the data service is set to DataServiceProtocolVersion.V1", and the status code of the reply is BadRequest(400).

*NOTE: We have decided to ship V2 with MaxProtocolVersion default to V1, for safety and compatibility reasons. You MUST explicitly set this to V2 in order to use any of the V2 features.