I asked almost the same question for me a month ago. I will describe my answer on the example of my implementation.
On the server side, I have a WFC service that receives requests in one of the following forms
GET /Service/RequestedData?param1=data1¶m2=data2… GET /Service/RequestedData/IdOfData?param1=data1¶m2=data2… PUT /Service/RequestedData/IdOfData // with param1=data1¶m2=data2… in body POST /Service/RequestedData/IdOfData // with param1=data1¶m2=data2… in body DELETE /Service/RequestedData/IdOfData
So the requests are in REST, but GET have some optional parameters. Especially this part is the port that interests you.
Because WFC supports URL patterns, a prototype of functions that respond to a client’s request looks like
[WebGet (UriTemplate = "RequestedData?param1={myParam1}¶m2={myParam2}", ResponseFormat = WebMessageFormat.Json)] [OperationContract] MyResult GetData (string myParam1, int myParam2);
All requests, for example
GET /Service/RequestedData?param1=¶m2=data2 GET /Service/RequestedData?param2=data2¶m1= GET /Service/RequestedData?param2=data2
will be mapped to the same call from my WCF service. So I have one less problem.
Now, at the beginning of the implementation of each method that responds to an HTTP GET , I set "Cache-Control: max-age = 0" in the HTTP header. This means that the client is always trying to check the client’s browser cache, and ajax requests will not easily respond from the local cache, as Internet Explorer can do.
Then I always calculate ETag based on my data. The exact algorithm is the subject of a separate discussion, but the important thing is that in all responses to HTTP GET requests there are ETag in the HTTP header.
Thus, clients check their local cache each time and send a GET request to the server. They send ETag that come from their local cache inside the < If-None-Match "HTTP header. The server calculates an ETag that has data that will be sent back to this GET request. It ETag the same ETag data on the request server the client sends back a response with an empty body and the code “ 304 Not Modified ” back, in which case the browser provides data from the local cache.
If for the unknown reason the same client creates a new version of the URL request that will be interpreted from the web browser as the new URL, then the web browser will not find the answer of the old server in the local cache and send the same request to the server one more time. Is this a real problem? The server sends the data again. If you have server-side caching, you can do a bit more optimization. In most cases, the GET request URL will be generated using client-side JavaScript, so you will not have this situation.
Calculation of ETag and setting the header " Cache-Control: max-age=0 " and ETag , as well as setting the code " 304 Not Modified " should perform the WFC service, but it is very simple.
Most importantly, my ETag calculation ETag not as expansive as getting all the data from the database server and computing the MD5 cache. I use the persistent rowversion data rowversion in every row of data in a SQL Server database. This rowversion not something else as the counter of changes in a database. If you change the rowversion data rowversion in the corresponding row, it will be enlarged. Therefore, if you make a SELECT from the maximum rowversion value, and this value does not change compared to previous queries, you can be sure that the data has not been changed over a period of time. The calculation algorithm ETa g should be sensitive only to deleting data from the table. But this is also a resolved issue. You can read a little more about this in the Concurrency Sql transaction processing .
I don’t want to offer my ETag calculation as the best choice, I just want to say that calculating ETag can be much cheaper than calculating MD5 from all the data.
In case of errors, the server throws an exception that will be mapped to the HTTP code that I define in the throw statement. How the WFC body sends a standard JSON object {"description":"My error text"} . A custom error object is also possible (see Is WebProtocolException Included in .net 4.0? ). On the client side, I use jQuery and in the corresponding jQuery.ajax inside the error event handler, the error message will be decoded and displayed to the user.
So my recommendation is: using ETag along with " Cache-Control: max-age=0 " for all HTTP GET requests. For all other requests, I recommend that you implement the RESTfull service. To implement the error, you should look at the most common method that is supported by the software used to implement the server and client, and use it.
UPDATED : To clear the URL structure, I have to add the following. In my service, the bulk of the type GET /Service/RequestedData/IdOfData describes the requested data objects. Parameters param1=data1¶m2=data2 correspond mainly to information about sorting, swapping and filtering data. I use the active jqGrid plugin for jQuery, and if the end user scrolls to the next page in the grid, click on the column heading (data sorting) or, if he sets a filter in relation to the search function, all this follows other optional parameters added by the main URL address.