Bessere Performance mit REST Kompression

Viele Delphi Anwendungen, speziell mobile iOS oder Android Apps, verwenden REST, um an ihre Daten zu gelangen. Häufig werden dazu TRESTClient und TRESTRequest eingesetzt, insbesondere wenn auf eine externe RESTAPI zugegriffen wird. Dies wird in einigen Blogs oder CodeRage Beiträgen (auch von mir) demonstriert. Zum Nachlesen findet sich auch in der Delphi Dokumentation ein einfaches Tutorial:

Delphi Songsterr REST Tutorial

Den meisten dieser Beispiele ist eines gemeinsam: Sie sind unnötig langsam!

Die meisten REST API’s werden auf mehr oder minder modernen Web Servern gehosted – sei es nun IIS, Apache, Nginx oder sonst was. All diese Server unterstützen normalerweise eine Kompression der HTTP(S) Kommunikation. Die eigentliche Implementation der API weiß davon in der Regel nichts.

Wenn man sich nun das Beispiel aus der Delphi Dokumentation ansieht und den folgenden Request in einem Webbrowser ausprobiert und sich dazu dann in der Entwicklerkonsole des Webbrowsers die übertragenen Daten ansieht, stellt man fest: „Prima, das geschwätzige XML wird auf 10% komprimiert„. Gerade bei mobilen Apps eine möglicherwiese enorme Zeitersparnis beim Übertragen der Daten:

https://www.songsterr.com/a/ra/songs.xml?pattern=Marley

In der Firefox Web Konsole läßt sich sehr schön der Kompressionsgewinn erkennen – hier werden die XML-Daten offenbar auf unter 10% eingedampft:

Komprimierte Daten

Wenn man nun den gleichen Test mit Delphi’s RESTDebugger (der intern TRESTClient verwendet) durchführt, dann sieht man sehr schnell das Problem:

Offenbar werden hier die Daten unkomprimiert übertragen – also unnötig langsam. Der Grund ist, dass ein HTTP-Server in der Regel die Kommunikation nicht „einfach so“ komprimiert. Der Browser/Client muss dem Server mitteilen, dass er gerne komprimierte Daten hätte. Ein handelsüblicher Webbrowser schickt daher automatisch bei jedem Request die Aufforderung an Server, dass er doch bitte komprimieren möge. Delphi’s TRESTClient macht genau das aber eben nicht automatisch.

Lösung:

procedure TForm1.Button1Click(Sender: TObject);
var
  LValue:TJSONValue;
begin
  RESTRequest1.AcceptEncoding := 'gzip, deflate, br';
  RESTRequest1.Execute;
  LValue:=RESTResponse1.JSONValue;
  MemoContent.Text:= LValue.ToString;
end;

Das fordert den Webserver auf, die Daten komprimiert, vorzugsweise per „gzip“ zurückzuschicken. Dies kann man durch einen „Header“ Parameter in Delphi’s RESTDebugger leicht nachvollziehen:

und schon komprimiert auch der TRESTClient die Daten:

Ob das Accept-Encoding per TRESTRequest.AcceptEncoding oder per explizitem Header-Paramter angeben wird, spielt keine Rolle. Wenn es über den Parameter gemacht wird, dann ist wichtig, dass im RESTDebugger die Checkbox „Nicht verschlüsseln“ angekreuzt wird, bzw. „DoNotEncode“ im Code:

  //Either like this
  LRequest.AcceptEncoding := 'gzip, deflate, br';
  //OR like this
  LParam := LRequest.Params.AddHeader('Accept-Encoding', 'br, gzip, deflate');
  LParam.Options := [poDoNotEncode];
  //--> same result!

 

Wir benutzen Cookies um die Nutzerfreundlichkeit der Webseite zu verbessen. Durch Deinen Besuch stimmst Du dem zu.