Als Conditional GET wird ein durch das HTTP-Protokoll unterstützter Mechanismus bezeichnet, der es Clients erlaubt, Dokumente lediglich unter der Bedingung, dass sie sich seit dem letzten Aufruf geändert haben, anzufordern. Hat sich das Dokument nicht geändert, antwortet der Server mit dem Statuscode 304 (Not Modified). Ansonsten wird das geänderte Dokument zurückgeliefert.
Um entscheiden zu können, ob sich ein Dokument geändert hat, sendet der Server mit den einzelnen Antworten einen sogenannten Entity Tag (ETag). Dieser beinhaltet einen Wert, welcher die aktuelle Version repräsentiert. Dabei kann es sich zum Beispiel um eine Versionsnummer, einen Zeitstempel oder einen Hashwert handeln. Bei weiteren Anfragen, welche sich auf dasselbe Dokument beziehen, sendet der Client diesen Wert an den Server zurück. Durch einen Vergleich mit dem aktuellen ETag kann dieser somit entscheiden, ob der Client bereits die aktuelle Version hat oder ob sich das Dokument seit dem letzten Abrufen geändert hat.
Ein? einfaches Beispiel für die Umsetzung dieses Konzepts mit ASP.NET Web API, der neuen "REST"-API aus dem Hause Microsoft, findet sich nachfolgend.
private string Quote(string str)
{
return "\"" + str + "\"";
}
public HttpResponseMessage<HotelBuchung> Get(int id/*, HttpRequestMessage request*/)
{
var request = this.Request; // HACK für BETA1
var rep = new HotelBuchungRepository();
var buchung = rep.FindById(id);
if (buchung == null)
{
return new HttpResponseMessage<HotelBuchung>(HttpStatusCode.NotFound);
}
// ETags befinden sich per Definition
// in doppelten Anführungszeichen!!
var etag = Quote(buchung.Version.ToString());
var ifNoneMatchHeader = request.Headers.IfNoneMatch.FirstOrDefault();
if (ifNoneMatchHeader != null && ifNoneMatchHeader.Tag == etag)
{
return new HttpResponseMessage<HotelBuchung>(HttpStatusCode.NotModified);
}
var response = new HttpResponseMessage<HotelBuchung>(buchung);
response.StatusCode = HttpStatusCode.OK;
response.Headers.CacheControl = new CacheControlHeaderValue();
response.Headers.CacheControl.NoCache = true;
response.Headers.ETag = new EntityTagHeaderValue(etag);
return response;
}