Bisher spricht die Kladde mit der Welt über HTTP und JSON: Browser, curl, der Client aus Lektion 2.12.2. Zwischen zwei eigenen Diensten gibt
es einen zweiten Weg, der in .NET zu Hause ist: gRPC. Der Vertrag ist dort keine Beschreibung, die man nachträglich erzeugt, sondern der
Ausgangspunkt, aus dem der Code entsteht; die Nachrichten sind binär und klein; und jeder Aufruf trägt eine Frist. In dieser Lektion lösen Sie
die Berechnung der freien Zeiten aus Lektion 2.5.6 probeweise als eigenen kleinen Dienst Kladde.Slots heraus, den die Webanwendung über
gRPC fragt. Es ist eine Übung: Die Kladde braucht für sich allein keinen zweiten Dienst. In K3 nehmen Sie den Dienst wieder auf.
Der Vertrag in Protobuf
Ein gRPC-Dienst beginnt mit einer .proto-Datei. Sie beschreibt die Methoden des Dienstes und die Nachrichten, die sie austauschen, in der
Sprache Protocol Buffers (Protobuf). Legen Sie im Branch spike-grpc ein neues Projekt an und darin Protos/slots.proto:
dotnet new web -n Kladde.Slots -o src/Kladde.Slots -f net10.0
dotnet solution Kladde.slnx add src/Kladde.Slots/Kladde.Slots.csproj
dotnet add src/Kladde.Slots package Grpc.AspNetCore --version 2.85.0
syntax = "proto3";
option csharp_namespace = "Kladde.Slots";
package kladde.slots.v1;
import "google/protobuf/timestamp.proto";
// The free slots of the office, computed from its opening hours and appointments.
service SlotService {
// The free slots of one day.
rpc GetFreeSlots (FreeSlotsRequest) returns (FreeSlotsReply);
// The free slots of several days, one message per day as soon as it is computed.
rpc StreamFreeDays (FreeDaysRequest) returns (stream FreeDay);
}
message FreeSlotsRequest {
string day = 1; // yyyy-MM-dd in the office's time zone
int32 minutes = 2; // length of one appointment
}
message FreeSlotsReply {
repeated FreeSlot slots = 1;
}
message FreeDaysRequest {
string first_day = 1;
int32 days = 2;
int32 minutes = 3;
}
message FreeDay {
string day = 1;
repeated FreeSlot slots = 2;
}
message FreeSlot {
google.protobuf.Timestamp start = 1;
int32 minutes = 2;
}
servicenennt die Methoden.GetFreeSlotsist unär: eine Anfrage, eine Antwort.StreamFreeDaysliefert mitstreameine Folge von Antworten, eine je Tag: Server-Streaming.messagesind die Nachrichten, mit Typen wiestring,int32undrepeatedfür Listen.- Die Zahl hinter jedem Feld ist seine Feldnummer. Auf der Leitung steht nicht der Name
minutes, sondern die Nummer 2. Darauf beruht alles, was weiter unten zur Weiterentwicklung kommt. google.protobuf.Timestampist ein fertiger Typ für Zeitpunkte. Er kennt keine Zeitzone, nur einen Zeitpunkt in UTC, wie einDateTimeOffsetohne Versatz. Den Tag des Büros schicken Sie deshalb als Text, so wie die API ihn in Lektion 2.3.9 alsDateOnlykennt.package kladde.slots.v1undcsharp_namespace: der Name des Dienstes auf der Leitung und der Namensraum im C#-Code. Dasv1im Paketnamen ist eine Konvention für den Tag, an dem es doch einmal eine unverträgliche Fassung braucht.