Skip to content
Language:hu Author:Laborci Gergely
web-api

API-verziózás, kompatibilitás és dokumentáció

Célok

A lecke végére el tudod dönteni, hogy egy API-változtatás visszafelé kompatibilis-e vagy törő, ismered a verziózás lehetőségeit, és meg tudod mondani, mit kell tartalmaznia egy használható API-dokumentációnak.

Miért kell kezelni az API változását?

Az API több kliens számára hosszú távú szerződés. A szerver azonban változik: új funkciók, átnevezések, javítások. A kliensek nem frissülnek ugyanabban a pillanatban: egy böngészős felület azonnal, egy mobilalkalmazás hetek vagy hónapok múlva, egy külső partner rendszere talán soha. Ha a szolgáltató egyik napról a másikra megváltoztatja a szerződést, a régi kliensek elromlanak, miközben a hálózat és a HTTP hibátlanul működik. A verziózás, a kompatibilitás és a dokumentáció teszi követhetővé és kezelhetővé a változást.

Egy mező átnevezése több kliensnél

A Kurzuspont API-ja eddig cim mezőt küldött. Az új szerverfejlesztés megnevezes-re nevezné át. Az új felület az új mezőt olvasná, a régi mobilalkalmazás viszont továbbra is cim-et vár. Kipróbálva, egy régi és egy újabb kliens ugyanazzal a három válasszal:

const regiKliens = v => "Kurzus: " + v.cim;
const ujKliens   = v => "Kurzus: " + (v.megnevezes ?? v.cim);
Szerverválasz Régi kliens Új kliens
{"id":"webprog","cim":"Webprogramozás 1."} (régi) Kurzus: Webprogramozás 1. Kurzus: Webprogramozás 1.
{"id":"webprog","megnevezes":"Webprogramozás 1."} (átnevezett) Kurzus: undefined Kurzus: Webprogramozás 1.
{"id":"webprog","cim":"...","megnevezes":"...","nyelv":"hu"} (bővített) Kurzus: Webprogramozás 1. Kurzus: Webprogramozás 1.

Az átnevezés elrontotta a régi klienst (undefined), a bővítés viszont nem. A harmadik megoldás átmenetileg a két mezőt együtt küldi, így mindkét kliens működik.

flowchart LR
    R[Régi kliens: cim] --> A[API-válasz]
    U[Új kliens: megnevezes] --> A
    A --> D[Kompatibilitási döntés]
    D --> M[Átmeneti együttélés vagy új verzió]

Kompatibilis és törő változás

Változás Hatása a régi kliensre Jellemzően
Új, opcionális válaszmező A régi kliens figyelmen kívül hagyhatja visszafelé kompatibilis
Új végpont A régi kliens nem használja kompatibilis
Kötelező mező eltávolítása A kliens nem találja törő
Mező átnevezése Mint fent törő
Mező típusának megváltoztatása (szám → szöveg) Típushibát okozhat (lásd 5.2) törő
Mező jelentésének megváltoztatása a név megtartásával Csendben hibás működés törő, különösen alattomos
Új kötelező kérésmező A régi kliens nem küldi törő

Az, hogy egy módosítás valóban kompatibilis-e, a tényleges szerződéstől és a kliensek viselkedésétől függ. A hibaválaszok (státuszkód, hibaformátum) is a szerződés részei: ha a kliens eddig egy adott státuszra és hibaformára számított, a változás ott is törheti a működést.

Verziózási lehetőségek

Az új verziót több módon lehet megkülönböztetni:

  • az útvonalban: /api/v2/kurzusok;
  • kérésfejlécben: például a kliens egy fejlécben vagy a médiatípusban jelzi a kért verziót;
  • a sémában: GraphQL esetén új mezők bevezetése és a régiek jelölése elavultként, verziószám nélkül.

Nincs egyetlen kötelező forma. A cél az, hogy a kliens tudja, melyik szerződést használja, és legyen átmenet, ha a régi verziót később kivezetik.

Mit tartalmazzon a dokumentáció?

Egy használható API-leírás megmondja:

  1. mire való a szolgáltatás és milyen hozzáférés kell hozzá;
  2. hol érhetők el a műveletek, milyen metódussal;
  3. milyen bemenet kell, mely mezők kötelezők vagy opcionálisak;
  4. milyen sikeres és hibás válasz várható (státuszkód és törzs);
  5. mit jelentenek a mezők, milyen típusúak, mi lehet hiányzó vagy null;
  6. hogyan változott a szerződés, mi van kivezetés alatt.

A példák segítenek, de nem helyettesítik a szabályok leírását: egy mintaválasz nem mondja meg, mi történik hiányzó adatnál vagy jogosultsági hibánál.

flowchart TD
    S[API-szerződés] --> M[Műveletek és bemenetek]
    S --> V[Válaszok és hibák]
    S --> A[Adatmezők jelentése]
    S --> K[Kompatibilitás és változások]

Az OpenAPI Specification nyelv- és gyártófüggetlen leírási forma HTTP API-khoz: a specifikáció szerint emberek és gépek a forráskód, a dokumentáció vagy a hálózati forgalom ismerete nélkül is megérthetik belőle, mit tud a szolgáltatás. A leírás gépi feldolgozásra is alkalmas (például kliens- vagy tesztkód generálására). Az oldal tanúsága szerint a specifikáció legfrissebb kiadása a 3.2.1. A jó dokumentáció azonban nem pusztán fájlformátum eredménye: a mezők pontos jelentése és a felhasználási feltételek is kellenek. GraphQL-nél a séma és a mezőleírások töltik be ugyanezt a szerepet.

Egy rövid OpenAPI-részlet a Kurzuspont GET /api/kurzusok/{id} műveletéhez (szemléltető, a szintaxist nem ellenőriztük validátorral):

paths:
  /api/kurzusok/{id}:
    get:
      summary: Egy kurzus lekérése
      parameters:
        - name: id
          in: path
          required: true
          schema: { type: string }
      responses:
        "200": { description: A kurzus }
        "404": { description: Nincs ilyen kurzus }

A szerződés próbája

A szolgáltató és a kliens együttműködését érdemes a régi és az új kliens szemszögéből is ellenőrizni: megkapja-e a régi kliens a szükséges mezőket? Érthetően reagál-e a hiányzó erőforrásra? Nem változott-e meg egy mező jelentése a név megtartása mellett? Ezek a kérdések a kompatibilitást konkrétan vizsgálják, nem csak egy verziószám meglétét.

Végigvezetett példa: a Kurzuspont v2-je

A Kurzuspont üzemeltetője át akarja nevezni a cim mezőt, és a ferohely mellé be akarja vezetni a szabadHely mezőt.

Lépés Döntés
szabadHely hozzáadása Opcionális bővítés, a régi kliensek figyelmen kívül hagyják: nem kell új verzió.
cim átnevezése megnevezes-re Törő változás. Átmenetileg mindkét mező megy (fenti harmadik sor), a cim pedig „elavultként” szerepel a dokumentációban.
Kivezetés A dokumentáció megadja a határidőt; a határidő után a cim megszűnik az új verzióban.
Dokumentáció OpenAPI-leírás, változásnapló, hibaformátum leírása.

Így a régi mobilalkalmazás frissítésére van idő, és senki nem látja egyik napról a másikra az undefined szöveget.

Gyakori tévhitek

Állítás Pontosítás
„Új szerververziónál minden kliens egyszerre frissül.” A kliensek eltérő ütemben változnak.
„Új mező mindig törő változás.” Az opcionális bővítés sok esetben kezelhető a régi kliensek számára.
„A verziószám önmagában megőrzi a kompatibilitást.” A régi szerződés fenntartása és az átmenet is kell.
„Egy mintaválasz teljes dokumentáció.” A hibák, feltételek és mezőjelentések külön leírást igényelnek.
„Az OpenAPI-fájl jó dokumentáció.” Fontos eszköz, de a mezők jelentése és a feltételek külön szöveg.

Röviden

  • Az API-szerződés hosszú életű, a kliensek különböző ütemben frissülnek.
  • A bővítés általában kompatibilis; az eltávolítás, átnevezés, típus- vagy jelentésváltás törő.
  • A verziót útvonal, fejléc vagy séma jelezheti; átmenet és kivezetési terv kell hozzá.
  • A jó dokumentáció a műveleteket, mezőket, hibákat és a változásokat is leírja.
  • Az OpenAPI gépileg olvasható leírás, de nem helyettesíti a mezők jelentésének leírását.

Ellenőrző kérdések

  1. Miért törő változás egy mező átnevezése, és miért nem az új opcionális mező?
  2. Hogyan lehet egy átnevezést fokozatosan bevezetni?
  3. Mit nem mond meg egy mintaválasz az API-ról?
  4. Miért veszélyes a mezők jelentésének csendes megváltoztatása?

Tanulási források

Prerequisites (2)

  • webes API
  • JSON

Teaches (2)

  • API-verziózás
  • API-dokumentáció