Strategier for skemaudvikling
Forstå teknikker til at videreudvikle Protobuf-skemaer uden at ødelægge eksisterende klienter eller services.
Strategier for skemaudvikling er en gratis gRPC og højtydende API'er-lektion på CoddyKit. Dette er lektion 2 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i gRPC og højtydende API'er, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. gRPC og højtydende API'er-kurset indeholder 4 lektioner i alt.
Hvorfor udvikling af skemaer er vigtig
I distribuerede systemer skal tjenester og klienter ofte kommunikere ved hjælp af et defineret dataformat, f.eks. Protocol Buffers (Protobuf).
Med tiden skal disse datastrukturer ændres. Måske skal du tilføje et nyt felt, fjerne et gammelt eller ændre en type.
Udvikling af skemaer er kunsten at ændre dine datadefinitioner uden at ødelægge eksisterende, ældre versioner af dine tjenester eller klienter. Det er afgørende for at bevare kompatibiliteten i dynamiske miljøer.
Udfordringen ved kompatibilitet
Når du opdaterer et skema, står du over for to primære udfordringer:
- Bagudkompatibilitet: Kan en ældre klient stadig kommunikere med en nyere server? Serveren skal kunne forstå den ældre klients anmodninger.
- Fremadkompatibilitet: Kan en nyere klient stadig kommunikere med en ældre server? Serveren skal ignorere nye felter, som den ikke forstår, på en korrekt måde.
Brud på kompatibiliteten kan føre til driftsafbrydelser og vanskelige udrulninger.
Protobufs nøgle: feltnumre
I modsætning til JSON, hvor feltnavne bruges til identifikation, bruger Protobuf unikke feltnumre til at identificere felter i dine meddelelser.
Disse numre er afgørende for kompatibiliteten. Når en meddelelse serialiseres, gemmes kun feltnumrene og deres værdier, ikke feltnavnene.
Det betyder:
- Feltnumre skal være unikke inden for en meddelelse.
- Når et feltnummer først er tildelt, må det aldrig ændres.
- Når et feltnummer først er tildelt, må det aldrig genbruges, heller ikke hvis feltet fjernes.
Strategi 1: Tilføjelse af nye felter
Det er generelt sikkert at tilføje nye felter, hvis du følger disse regler:
- Tildel et nyt, ubrugt feltnummer.
- Gør det nye felt
optional(ellerrepeated,mapiproto3).
Ældre klienter ignorerer ganske enkelt det nye felt. Nye klienter, der kommunikerer med ældre servere, bruger feltets standardværdi, hvis feltet ikke findes.
Prøv at køre dette Java-kodeeksempel for at se, hvordan en Protobuf-genereret meddelelse håndterer et nyt felt:
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.util.JsonFormat;
// Assume these classes are generated from .proto files:
// Original: message User { string name = 1; }
// Evolved: message User { string name = 1; int32 age = 2; }
// We'll simulate the User class for demonstration purposes.
class User {
private final String name;
private final int age;
private User(Builder builder) {
this.name = builder.name;
this.age = builder.age;
}
public String getName() { return name; }
public int getAge() { return age; }
public static Builder newBuilder() { return new Builder(); }
public static class Builder {
private String name = "";
private int age = 0; // Default value for new field
public Builder setName(String name) { this.name = name; return this; }
public Builder setAge(int age) { this.age = age; return this; }
public User build() { return new User(this); }
}
@Override
public String toString() { return "User{name='" + name + "', age=" + age + "}"; }
}
public class AddFieldEvolution {
public static void main(String[] args) {
// Simulate an old client sending data (unaware of 'age')
User oldClientUser = User.newBuilder()
.setName("Alice")
.build();
System.out.println("Old client sends: " + oldClientUser);
// Simulate a new server receiving this data.
// The 'age' field will correctly default to 0.
System.out.println("New server receives (age): " + oldClientUser.getAge());
// Simulate a new client sending data (aware of 'age')
User newClientUser = User.newBuilder()
.setName("Bob")
.setAge(30)
.build();
System.out.println("New client sends: " + newClientUser);
// Simulate an old server receiving this data.
// It will simply ignore the 'age' field.
System.out.println("Old server receives (name only): " + newClientUser.getName());
}
}Strategi 2: Fjernelse af felter
Du bør aldrig slette et feltnummer helt, da det kan føre til datakorruption, hvis nummeret genbruges senere.
Markér i stedet felter som deprecated, og reserver dem med reserved:
- Brug indstillingen
deprecated = truefor at angive, at feltet ikke længere bør bruges. Kompilatorer udsender advarsler. - Brug nøgleordet
reservedfor at forhindre fremtidig tildeling af bestemte feltnumre eller navne. Det sikrer, at nummeret aldrig genbruges ved en fejl.
Sådan markerer du et felt som forældet og reserverer dets nummer:
syntax = "proto3";
package evolution;
message OldMessage {
string id = 1;
// This field is deprecated and should not be used.
string old_data = 2 [deprecated = true];
string new_data = 3;
// Reserve field number 2 and the name 'old_data'
// to prevent accidental reuse in the future.
reserved 2;
reserved "old_data";
}Strategi 3: Omdøbning af felter
Husk, at Protobuf identificerer felter ved hjælp af deres feltnumre, ikke deres navne. Derfor er det en kompatibel ændring blot at ændre et felts navn i .proto-filen.
Hvis du også skal ændre feltnummeret, svarer det imidlertid reelt til en handling, hvor feltet først fjernes og derefter tilføjes igen. I sådanne tilfælde:
- Markér det gamle feltnummer som
reserved. - Tilføj et nyt felt med det nye navn og et nyt, ubrugt feltnummer.
Det sikrer, at gamle klienter og servere ikke forveksles af modstridende feltnumre.
Strategi 4: Ændring af felttyper
Ændring af et felts type er ofte hverken bagud- eller fremadkompatibel og bør foretages med stor forsigtighed.
Nogle sikre ændringer:
int32tilint64(værdier afkortes, hvis de læses af en gammel klient).uint32tiluint64.
Usikre ændringer (ødelægger kompatibiliteten):
int32tilstring.int32tilfixed32.- Alle ændringer, der involverer
enum,messageellerbytestil andre typer.
Hvis en usikker typeændring ikke kan undgås, skal du behandle den som en fjernelse af det gamle felt efterfulgt af tilføjelse af et nyt felt med et nyt nummer.
Strategi 5: Udvikling af enums
Enums repræsenteres som heltal. Det er generelt sikkert at tilføje nye værdier til en enum, men følg disse regler:
- Tilføj altid nye enum-værdier til slutningen af listen.
- Tildel en ny, ubrugt heltalsværdi.
- Ændr aldrig den numeriske værdi for et eksisterende enum-medlem.
Ældre klienter, der møder en ny enum-værdi, vil typisk se dens heltalsrepræsentation, som de måske ikke håndterer korrekt, hvis de kun forventer kendte værdier. Medtag altid en 0-værdi som det første enum-medlem af hensyn til kompatibiliteten.
syntax = "proto3";
package evolution;
message StatusUpdate {
Status current_status = 1;
}
enum Status {
UNKNOWN = 0;
PENDING = 1;
PROCESSING = 2;
// New status added (safe)
COMPLETED = 3;
// Another new status (safe)
FAILED = 4;
}Strategi 6: Udvikling af oneof-felter
Et oneof-felt betyder, at højst ét af felterne i oneof-gruppen kan være angivet ad gangen.
Udvikling af oneof-felter følger lignende regler:
- Tilføjelse af nye felter til en
oneofer kompatibel. Tildel et nyt, ubrugt feltnummer. Ældre klienter ignorerer disse nye tilfælde. - Fjernelse af felter fra en
oneofkræver, at feltnummeret markeres som forældet og reserveres, ligesom almindelige felter.
Vær forsigtig, når du ændrer eksisterende felter i en oneof, da det kan påvirke kompatibiliteten.
Hurtig kontrol: Skemaregler
Hvilken af følgende handlinger betragtes generelt som usikker og vil sandsynligvis ødelægge Protobuf-kompatibiliteten?
Opsummering: Sikker udvikling af skemaer
Tillykke! Du har lært de vigtigste strategier til sikker udvikling af dine Protobuf-skemaer:
- Feltnumre: Er afgørende og skal være unikke og stabile. Du må aldrig ændre eller genbruge dem.
- Tilføjelse af felter: Tildel altid nye numre; nye felter ignoreres af gamle klienter.
- Fjernelse af felter: Markér feltnumre som forældede, og reservér dem for at forhindre fremtidig genbrug.
- Omdøbning af felter: Du må kun ændre navnet, ikke nummeret, eller skal behandle ændringen som en fjernelse og tilføjelse.
- Typeændringer: Er for det meste usikre; undgå dem, eller behandl dem som en fjernelse og tilføjelse.
- Enums: Tilføj nye værdier til slutningen, og ændr aldrig eksisterende numre.
Ved at følge disse retningslinjer kan du sikre, at dine gRPC-tjenester forbliver kompatible, mens de udvikler sig.
Lær gRPC og højtydende API'er med en AI-underviser — gratis
Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.
- Kurser
- 12
- Lektioner
- 48
Ofte stillede spørgsmål
Er lektionen “Strategier for skemaudvikling” gratis?
Ja — hele teksten til “Strategier for skemaudvikling” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af gRPC og højtydende API'er-kurset, skal du opgradere til CoddyKit PRO. gRPC og højtydende API'er-kurset indeholder 4 lektioner i alt.
Hvad lærer jeg i “Strategier for skemaudvikling”?
Forstå teknikker til at videreudvikle Protobuf-skemaer uden at ødelægge eksisterende klienter eller services. Du øver dig i gRPC og højtydende API'er med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.
Skal jeg have erfaring for at begynde på gRPC og højtydende API'er?
Der kræves ingen tidligere erfaring. gRPC og højtydende API'er på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 2 af 4.
Hvor lang tid tager lektionen “Strategier for skemaudvikling”?
De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.
Kan jeg skrive og køre kode i denne gRPC og højtydende API'er-lektion?
Ja. Alle gRPC og højtydende API'er-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.
Alle lektioner i dette kursus
- Bedste praksis for Protobuf
- Strategier for skemaudvikling
- Brugerdefinerede Protobuf-indstillinger
- Oneof, maps og velkendte typer