Umstieg auf .NET Core, Teil 4: SOAP- und REST-Webservices umstellen

Seite 3: Google RPC als Alternative zu WCF

Inhaltsverzeichnis

Angesichts dieser Herausforderungen stellt sich die Frage nach Alternativen zu Core WCF. Microsoft unterstützt neben den REST-basierten ASP.NET Core WebAPIs seit .NET Core 3.0 auch Google Remote Procedure Call (gRPC). Seitdem Microsoft sich der Open-Source-Welt geöffnet hat, gibt es auch keine Berührungsängste mit dem Suchmaschinenkonzern mehr.

gRPC verwendet als Transportprotokoll HTTP/2 (immer abgesichert mit SSL-/TLS-Transportsicherheit) und zur Serialisierung ein binäres Format mit Namen Protocol Buffers. Zu Protocol Buffers gehört auch ein textbasiertes Metadatenformat, das im Sinne des Contract-First-Designs der Ausgangspunkt der Entwicklung ist. Hieraus generiert der Protocol-Buffers-Compiler Quellcode in verschiedenen Programmiersprachen. Es existieren gRPC-Implementierungen für zahlreiche Programmierplattformen und -sprachen wie z.B. C++, C#, PHP, Java, Ruby, Python, Dart, Objective-C und JavaScript, nicht nur auf der Serverseite mit Node.js, sondern – in eingeschränkter Form – auch im Webbrowser (gRPC-Web). Microsoft bietet seit 27. Januar 2020 eine .NET-basierte gRPC-Web-Implementierung, die ohne den bei gRPC üblichen Proxy auskommt. Somit können Blazor-WebAssembly-Anwendungen direkt mit gRPC-Diensten sprechen.

Microsoft und Google arbeiten zusammen an der C#-Implementierung von gRPC. Hier taucht der bei Microsoft angestellte James Newton-King nun wieder als aktivster Entwickler auf. Microsoft liefert im .NET Core SDK (seit Version 3.0) und Visual Studio (seit Version 2019 16.3) Projektvorlagen für das Erstellen von gRPC-Servern. Ein gRPC-Server in .NET Core basiert auf ASP.NET Core. Ein Serverprozess kann sowohl WebAPI- als auch gRPC-Dienste hosten – unter verschiedenen URLs versteht sich. Allerdings können gRPC-Dienste derzeit nur im Kestrel-Webserver laufen. Weder die Internet Information Services (IIS) sowie die abgespeckte Version IIS Express noch ein Hosting in einem Azure App Service in der Cloud sind bislang möglich.

Aus der Sicht von Microsoft ist die Umstellung von WCF auf gRPC der favorisierte Weg, den der Softwarehersteller aus Redmond im Abschnitt Migrate a WCF solution to gRPC in der Dokumentation zu gRPC auf .NET Core ausführlich beschreibt. Die Vorgehensweise erfordert jedoch umfassende Handarbeit.

Großen Aufwand verursacht zunächst das manuelle Erstellen der Protobuffers-Dienst- und Nachrichtenspezifikation im Textformat (.proto-Datei) auf Basis der WCF-Data- und Service-Vertragsklassen, die bei WCF in C#- oder Visual Basic-Syntax vorliegen. Mit dem Protobuffers-Compiler (NuGet-Paket Grpc.Tools) für C# generiert man in Visual Studio oder auf der Kommandozeile aus der .proto-Datei dann wieder C#-Programmcode. Es entstehen Klassen sowohl für die ein- und ausgehenden Nachrichten als auch abstrakte Basisklassen für die Dienste. Entwickler erstellen eine davon abgeleitete gRPC-Dienstklasse und überführen hier hinein dann die WCF-Service-Implementierung.

Eine Herausforderung ergibt sich dadurch, dass Protobuffers immer nachrichtenorientiert ist. Das heißt, es gibt bei Diensten keine primitiven Ein- und Ausgabeparameter, sondern immer jeweils eine ein- und ausgehende Nachrichtenklassen. Dies war auch bei WCF der empfohlene Weg in Hinblick auf Schnittstellenevolution, aber dennoch haben einige .NET-Entwickler mit primitiven Parametern gearbeitet. In diesem Fall ist der Weg zu gRPC etwas weiter.

Sofern man in der bisherigen Anwendung schon die von der Datenzugriffsschicht gelieferten Datenklassen auf eigene Nachrichtenklassen (alias Datentransferklassen) abgebildet hat, muss man nur das Mapping ändern. In WCF war es aber auch möglich, die Datenklassen der Datenzugriffsschicht direkt als Nachrichtenklassen zu verwenden. In dieser Architektur ist dann ein neues, zusätzliches Objekt-zu-Objekt-Mapping oder eine Änderung der Datenzugriffsschicht fällig.

Einen Client-Proxy für einen gRPC-Dienst können Entwickler in .NET Core- und .NET Standard-Projekten in Visual Studio komfortabel mit der integrierten Funktion "Add Connected Services" generieren lassen, wie in Abbildung 1 oben zu sehen.

Spannend ist die Frage, wie sehr man von der Umstellungsarbeit profitiert. Die Antwort liefert Abbildung 2. Die Leistung gRPC-basierter Dienste entspricht bei kleinen Nachrichten der Leistung von WCF mit TCP und Binärprotokoll – in der unverschlüsselten Form. Bei größeren Nachrichten bietet gRPC einen Vorteil.

Da gRPC aber stets Transport Layer Security (TLS) verwendet, ist der direkte Maßstab der dritte Block in der Grafik (WCF TCP + Verschlüsselung / binär). Da liegt gRPC schon deutlicher vorne. Klarer Sieger ist gRPC gegenüber WCF HTTP und HTTP-basierten WebAPIs. gRPC ist dabei verschlüsselt schneller als WCF und WebAPI unverschlüsselt. Der lange Balken in der Mitte ergibt sich daraus, dass bei der Messung bei WCF HTTP mit nachrichtenbasierter Sicherheit (WS-Security) statt Transportsicherheit (SSL/TLS) gearbeitet wurde. Bei gRPC gibt es weder WS-Security noch andere WS-+-Protokolle wie WS-Transaction, WS-Coordination, WS-ReliableMessaging, WS-Federation, WS-Policy und WS-Discovery.

Leistungsvergleich von WCF, WebAPI und gRPC mit einem direkten Datenbankzugriff ("2-Tier") (Abb. 3)