gRPC og høyytelses-API-er · leksjon

Strategier for skjemautvikling

Forstå teknikker for å videreutvikle Protobuf-skjemaer uten å bryte eksisterende klienter eller tjenester.

Leksjon 2 av 411 trinn

Strategier for skjemautvikling er en gratis leksjon i gRPC og høyytelses-API-er på CoddyKit. Dette er leksjon 2 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i gRPC og høyytelses-API-er, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i gRPC og høyytelses-API-er inneholder totalt 4 leksjoner.

Hvorfor videreutvikling av skjemaer er viktig

I distribuerte systemer må tjenester og klienter ofte kommunisere ved hjelp av et definert dataformat, for eksempel Protocol Buffers (Protobuf).

Over tid må disse datastrukturene endres. Kanskje må du legge til et nytt felt, fjerne et gammelt eller endre en type.

Videreutvikling av skjemaer handler om å endre datadefinisjonene uten å bryte eksisterende, eldre versjoner av tjenestene eller klientene dine. Dette er avgjørende for å opprettholde kompatibilitet i miljøer som stadig endrer seg.

Kompatibilitetens utfordring

Når du oppdaterer et skjema, møter du to hovedutfordringer:

  • Bakoverkompatibilitet: Kan en eldre klient fortsatt kommunisere med en nyere server? Serveren må forstå forespørslene fra den eldre klienten.
  • Fremoverkompatibilitet: Kan en nyere klient fortsatt kommunisere med en eldre server? Serveren må ignorere nye felt den ikke forstår, på en god måte.

Brudd på kompatibiliteten kan føre til driftsavbrudd og krevende utrullinger.

Protobufs nøkkel: feltnumre

I motsetning til JSON, der feltnavn brukes til identifikasjon, bruker Protobuf unike feltnumre til å identifisere felt i meldingene dine.

Disse numrene er avgjørende for kompatibiliteten. Når en melding serialiseres, lagres bare feltnumrene og verdiene deres, ikke feltnavnene.

Dette betyr:

  • Feltnumre må være unike i en melding.
  • Når et feltnummer først er tildelt, bør det aldri endres.
  • Når et feltnummer først er tildelt, bør det aldri brukes på nytt, selv om feltet fjernes.

Strategi 1: Legge til nye felt

Det er som regel trygt å legge til nye felt, så lenge du følger disse reglene:

  • Tildel et nytt, ubrukt feltnummer.
  • Gjør det nye feltet optional (eller repeated eller map i proto3).

Gamle klienter ignorerer ganske enkelt det nye feltet. Nye klienter som kommuniserer med gamle servere, bruker feltets standardverdi hvis feltet ikke finnes.

Prøv å kjøre dette Java-kodeeksempelet for å se hvordan en Protobuf-generert melding håndterer et nytt 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: Fjerne felt

Du bør aldri slette et feltnummer fullstendig, siden dette kan føre til datakorrupsjon hvis nummeret brukes på nytt senere.

Merk i stedet felt som deprecated og reserved:

  • Bruk alternativet deprecated = true for å angi at feltet ikke lenger skal brukes. Kompilatorer vil vise advarsler.
  • Bruk nøkkelordet reserved for å hindre fremtidig tildeling av bestemte feltnumre eller navn. Dette sikrer at nummeret aldri brukes på nytt ved en feil.

Slik merker du et felt som foreldet og reserverer nummeret:

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: Gi felt nye navn

Husk at Protobuf identifiserer felt ved hjelp av feltnumre, ikke navnene deres. Derfor er det en kompatibel endring å bare endre navnet på et felt i .proto-filen.

Hvis du også må endre feltnummeret, tilsvarer dette i praksis en «fjern»-operasjon etterfulgt av en «legg til»-operasjon. I slike tilfeller:

  • Merk det gamle feltnummeret som reserved.
  • Legg til et nytt felt med det nye navnet og et nytt, ubrukt feltnummer.

Dette hindrer at gamle klienter eller servere blir forvirret av motstridende feltnumre.

Strategi 4: Endre felttyper

Å endre typen til et felt er ofte verken bakover- eller fremoverkompatibelt og bør gjøres med stor forsiktighet.

Noen trygge endringer:

  • int32 til int64 (verdier vil bli avkortet hvis de leses av en gammel klient).
  • uint32 til uint64.

Utrygge endringer (vil bryte kompatibiliteten):

  • int32 til string.
  • int32 til fixed32.
  • Alle endringer som involverer enum, message eller bytes til andre typer.

Hvis en utrygg typeendring ikke kan unngås, bør du behandle den som om du fjerner det gamle feltet og legger til et nytt med et nytt nummer.

Strategi 5: Videreutvikle enums

Enums representeres som heltall. Det er som regel trygt å legge til nye verdier i en enum, men følg disse reglene:

  • Legg alltid nye enum-verdier til på slutten av listen.
  • Tildel en ny, ubrukt heltallsverdi.
  • Endre aldri tallverdien til et eksisterende enum-medlem.

Gamle klienter som møter en ny enum-verdi, vil vanligvis se heltallsrepresentasjonen av den. De håndterer den kanskje ikke på en god måte hvis de forventer bare kjente verdier. Inkluder alltid en verdi 0 som det første enum-medlemmet for å sikre kompatibilitet.

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: Videreutvikle oneof-felt

Et oneof-felt betyr at høyst ett av feltene i oneof-gruppen kan være satt om gangen.

Videreutvikling av oneof-felt følger lignende regler:

  • Å legge til nye felt i en oneof er kompatibelt. Tildel et nytt, ubrukt feltnummer. Gamle klienter vil ignorere disse nye tilfellene.
  • Å fjerne felt fra en oneof krever at feltnummeret foreldes og reserveres, på samme måte som for vanlige felt.

Vær forsiktig når du endrer eksisterende felt i en oneof, siden dette kan påvirke kompatibiliteten.

Hurtigsjekk: Skjemaregler

Hvilken av følgende handlinger regnes vanligvis som utrygg og vil sannsynligvis bryte Protobuf-kompatibiliteten?

Oppsummering: Trygg videreutvikling av skjemaer

Gratulerer! Du har lært de viktigste strategiene for å videreutvikle Protobuf-skjemaer på en trygg måte:

  • Feltnumre: Er avgjørende og må være unike og stabile. Endre eller bruk dem aldri på nytt.
  • Legge til felt: Tildel alltid nye numre; gamle klienter ignorerer nye felt.
  • Fjerne felt: Merk feltnumre som foreldet og reserver dem for å hindre fremtidig gjenbruk.
  • Gi felt nye navn: Endre bare navnet, ikke nummeret, eller behandle endringen som en fjerning og tilføyelse.
  • Typeendringer: Er stort sett utrygge; unngå dem eller behandle dem som en fjerning og tilføyelse.
  • Enums: Legg nye verdier til på slutten, og endre aldri eksisterende numre.

Ved å følge disse retningslinjene kan du sikre at gRPC-tjenestene dine forblir kompatible mens de videreutvikles.

Gratis å komme i gang

Lær deg gRPC og høyytelses-API-er med en AI-veileder – gratis

Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.

Kurs
12
Leksjoner
48

Ofte stilte spørsmål

Er leksjonen «Strategier for skjemautvikling» gratis?

Ja – hele teksten i «Strategier for skjemautvikling» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av gRPC og høyytelses-API-er-kurset, kan du oppgradere til CoddyKit PRO. Kurset i gRPC og høyytelses-API-er inneholder totalt 4 leksjoner.

Hva lærer jeg i «Strategier for skjemautvikling»?

Forstå teknikker for å videreutvikle Protobuf-skjemaer uten å bryte eksisterende klienter eller tjenester. Du øver på gRPC og høyytelses-API-er med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.

Trenger jeg erfaring for å begynne med gRPC og høyytelses-API-er?

Ingen tidligere erfaring er nødvendig. gRPC og høyytelses-API-er på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 2 av 4.

Hvor lang tid tar leksjonen «Strategier for skjemautvikling»?

De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.

Kan jeg skrive og kjøre kode i denne gRPC og høyytelses-API-er-leksjonen?

Ja. Alle gRPC og høyytelses-API-er-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.

Alle leksjonene i dette kurset

  1. Anbefalte fremgangsmåter for Protobuf
  2. Strategier for skjemautvikling
  3. Egendefinerte Protobuf-alternativer
  4. Oneof, maps og velkjente typer
← Tilbake til gRPC og høyytelses-API-er