Header-ul Sunset al unui API și când să-l trimiți
5 min de citit
Sunset e un singur header de răspuns, definit în RFC 8594,
care spune unui apelant când o resursă va înceta să răspundă. Deprecierea API
acoperă întregul calendar anunț-memento-brownout-retragere și notificările care îl însoțesc; acest
text e despre singurul semnal lizibil de mașină din acel calendar, ce spune el de fapt, și singurul
caz în care RFC-ul însuși spune să nu-l trimiteți.
Ce spune header-ul Sunset, și ce nu spune?
Poartă o singură dată HTTP, momentul la care resursa e de așteptat să devină nefuncțională:
Sunset: Sat, 31 Dec 2028 23:59:59 GMT
RFC-ul îl numește un indiciu, nu o garanție: nu promite că resursa va continua să funcționeze până exact la acel moment, și nu spune nimic despre cum va arăta eșecul după aceea. Apelanții pot primi un 4xx, o redirecționare, sau niciun răspuns; header-ul nu face distincția. O dată deja trecută înseamnă “acum, sau oricând” și nu o eroare în valoare. Nimic din asta nu e impus de protocol. Un client care nu citește niciodată header-ul se comportă exact ca înainte, și află că resursa a dispărut exact cum ar fi aflat oricum.
Când ar trebui de fapt să-l trimiteți?
Doar odată ce resursa chiar urmează să înceteze să răspundă, nu cât timp e doar opțiunea care nu mai e recomandată. RFC-ul e explicit că deprecierea se întâmplă în două etape, iar header-ul Sunset aparține doar celei de-a doua: API-ul rămâne complet funcțional în prima etapă, anunțul că o versiune nu mai e preferată, iar header-ul nu se aplică acolo. Se aplică odată ce versiunea e chiar programată să devină nefuncțională.
Asta se mapează direct pe calendarul deprecierii: header-ul Deprecation pleacă din prima zi, la
pasul de anunț; Sunset descrie data la care comportamentul vechi chiar se oprește, aceeași dată pe
care calendarul în patru pași o numește retragere. Trimiterea
Sunset-ului din prima zi nu e greșită, din moment ce data e deja fixată atunci, dar trimiterea lui
fără să fi anunțat și o depreciere, sau fixarea lui pentru o versiune pe care nu v-ați angajat de
fapt s-o retrageți, le spune apelanților ceva ce încă n-ați decis.
Interacționează cu cache-ul?
Nu, iar RFC-ul o spune direct: Sunset și cache-ul HTTP rezolvă probleme fără legătură între ele
și ar trebui citite ca fiind complementare, nu suprapuse. Header-ele de cache spun când o copie din
cache e sigură de refolosit; Sunset nu spune nimic despre starea curentă a resursei, doar că
resursa însăși va înceta să existe. Un răspuns poate fi complet cacheabil chiar până în momentul în
care se retrage. Nu folosiți unul ca aproximare pentru celălalt, și nu presupuneți că un max-age
lung anulează o dată de sunset apropiată, sau invers.
Poate un singur header retrage mai mult de un endpoint?
Header-ul se aplică resursei care l-a returnat, dar RFC-ul permite unui serviciu să documenteze un domeniu mai larg: o dată Sunset pe resursa principală a unui API poate fi definită să însemne că tot API-ul dispare, nu doar acel URL. Problema e că asta funcționează doar pentru apelanții care cunosc deja regula voastră de domeniu. Un apelant care citește header-ul la propriu vede un sunset doar pe resursa pe care a cerut-o și nimic altceva, așa că un domeniu mai larg trebuie scris undeva unde apelantul îl poate găsi, nu doar subînțeles.
Ce ar trebui să însoțească header-ul?
Un link către locul unde e explicată retragerea. RFC 8594 înregistrează propria relație de link
sunset exact pentru asta: indică o resursă care descrie politica de retragere, data viitoare, sau
cum se face migrarea, separat de simpla dată din header.
HTTP/1.1 200 OK
Sunset: Sat, 31 Dec 2028 23:59:59 GMT
Link: <https://example.com/docs/sunset-policy>; rel="sunset"
Îndreptarea acestui link către propriile voastre exemple de changelog sau
către o pagină dedicată de migrare transformă un header pe care aproape niciun cod client nu-l
inspectează în ceva ce un om care chiar caută găsește imediat. Combinați-l cu relația
successor-version din header-ele de depreciere
și un apelant primește, doar din răspuns, atât unde să meargă cât și ce înlocuiește resursa asta.
Cum arată asta cap la coadă?
Să spunem că v1 dispare pe 1 martie 2027. Anunțul de depreciere din prima zi adaugă
Deprecation și Link: rel="successor-version" la fiecare răspuns v1, conform header-elor de
depreciere, dar amână Sunset până când data de retragere e chiar
fixată, nu doar un substituent. Odată fixată, fiecare răspuns v1 poartă:
HTTP/1.1 200 OK
Deprecation: @1756425600
Sunset: Mon, 01 Mar 2027 00:00:00 GMT
Link: <https://api.example.com/v2/reports>; rel="successor-version"
Link: <https://example.com/docs/sunset-policy>; rel="sunset"
Gateway-ul sau monitorizarea unui apelant poate alerta pe baza fiecărui header independent:
Deprecation spune că există o versiune mai nouă, Sunset spune că asta are un ceas care curge.
Niciun header nu trebuie să se schimbe înainte de 1 martie; ce se schimbă e răspunsul însuși, în
ziua respectivă, și în timpul oricăror ferestre de brownout programate înainte de ea.
Schimbă un brownout ce spune header-ul?
Valoarea header-ului în sine nu trebuie să se miște pentru un brownout programat: data de sunset
rămâne data de sunset, indiferent dacă resursa eșuează intermitent înainte de ea. Ce se schimbă e
răspunsul, nu header-ul. Programarea unor ferestre scurte de 410 Gone în săptămânile dinaintea
datei anunțate, așa cum descrie deprecierea API, e ceea ce transformă
primul contact al unui apelant cu eșecul într-o repetiție, nu evenimentul real din ziua în care
sosește data header-ului.
FAQ
Chiar citesc clienți sau unelte HTTP reale header-ul Sunset? Rareori, pe partea de client. Valoarea lui e mai ales pentru cine operează infrastructura dintre voi și apelant: un API gateway sau o unealtă de monitorizare pe care o configurați să urmărească header-ul poate alerta propria voastră echipă, sau pe a unui partener, cu mult înainte ca vreodată codul apelantului să observe. Tratați-l ca pe un semnal în jurul căruia construiți unelte, nu ca pe unul pe care puteți presupune că partea cealaltă îl are deja.
Sunset e același lucru cu Cache-Control: max-age?
Nu. max-age e despre cât timp rămâne valabilă o copie din cache; Sunset e despre când
încetează resursa să existe deloc. Un răspuns poate avea un max-age scurt și o dată Sunset la
ani distanță, sau invers, și niciun header nu-l constrânge pe celălalt.
Pot trimite Sunset pentru un singur câmp care dispare, nu pentru tot endpoint-ul?
Nu, header-ul e limitat la resursă, adică la URL, nu la un câmp din corpul răspunsului. Pentru un
câmp, un parametru sau o valoare enum care dispare cât timp endpoint-ul rămâne activ, folosiți în
schimb header-ul Deprecation și o intrare de changelog; deprecierea API
acoperă exact anunțarea acestui tip de schimbare.
Ce se întâmplă dacă data de sunset trebuie mutată? Actualizați valoarea header-ului și spuneți asta în intrarea de changelog care a anunțat-o inițial; schimbarea tăcută a unei date publicate e exact cum decide un apelant că niciuna dintre datele voastre nu e reală. RFC-ul încadrează valoarea ca un indiciu tocmai pentru că datele chiar se mută uneori, dar o dată mutată fără explicație vă costă și pe următoarea.
Afirmațiile tehnice din acest articol nu au fost verificate independent. Dacă ceva nu e corect, spune-ne și vom corecta.