Salta ai contenuti

Regole di stabilità per la SPI

La service provider interface di NextPDF segue il Semantic Versioning. Ogni contratto pubblico riporta un tag @stability e una promessa di compatibilità all’indietro. Questa pagina enuncia le regole per aiutare a decidere su cosa fare affidamento.

Terminal window
composer require nextpdf/core:^3

La service provider interface è l’insieme dei contratti pubblici nei namespace NextPDF\Contracts e NextPDF\Event. Un tipo fa parte dell’interfaccia solo quando il PHPDoc nel relativo sorgente riporta un tag @stability. Il tag definisce il confine. Un tipo privo del tag è interno, anche se in PHP è tecnicamente public.

NextPDF segue il Semantic Versioning 2.0.0. Una modifica incompatibile apportata a un contratto stable incrementa la versione major. Un nuovo contratto o un’aggiunta compatibile incrementa la versione minor. Una correzione di bug incrementa la versione patch.

Ogni contratto dichiara uno di tre valori di stabilità:

TagSignificatoRegola di modifica
stablePronto per la produzione. Affidabile come dipendenza.Nessuna modifica incompatibile in una release minor o patch. I nuovi metodi vengono aggiunti solo con un comportamento predefinito oppure su un nuovo contratto.
experimentalUtilizzabile ma non ancora congelato.L’interfaccia può cambiare in una release minor, preceduta da un avviso di deprecazione.
deprecatedPianificato per la rimozione.Il contratto indica la sostituzione e la versione di rimozione.

La promessa di ogni contratto è registrata nella contracts map generata e viene rigenerata dal sorgente a ogni release. Il testo della promessa indica la regola esatta per quel contratto. Consultare il PHPDoc nel sorgente del contratto come unica fonte di verità.

Classi di promessa di compatibilità all’indietro

Sezione intitolata “Classi di promessa di compatibilità all’indietro”

La contracts map registra la promessa. Le promesse rientrano in quattro classi:

  1. Promessa di interfaccia. «Nessuna modifica incompatibile in una release minor o patch. Nuovi metodi solo con un’implementazione predefinita.» Si applica alla maggior parte delle interfacce stable, tra cui FontRegistryInterface, SignerInterface, HsmSignerInterface e HtmlSecurityPolicyInterface.
  2. Promessa di enum. «Nessuna rimozione di case. Nuovi case possono essere aggiunti in una versione minor.» Si applica agli enum stable, come Alignment, Orientation e OutputDestination.
  3. Promessa di value object congelato. «La firma del costruttore e le proprietà pubbliche sono congelate. Nuovi metodi possono essere aggiunti.» Si applica ai value object come TextPreprocessResult, TextSegment e ai payload di evento a essi associati.
  4. Promessa sperimentale. «L’interfaccia può cambiare in una versione minor con un avviso di deprecazione.» Si applica ai contratti experimental come DeferredSignerInterface, TimestampProviderInterface, CursorInterface e StreamingWriterInterface.

Una classe final come EventDispatcher o ListenerProvider congela le firme dei propri metodi pubblici. Estendere una classe final tramite composizione, senza crearne sottoclassi.

CursorInterface e StreamingWriterInterface sono experimental (a partire dalla 3.1.0). NextPDF fornisce un’implementazione del motore finale e testata per entrambi i contratti; le classi di implementazione sono interne e non fanno parte della superficie pubblica. Il comportamento di streaming si usa tramite il contratto pubblico experimental. Nel caso comune non occorre implementare direttamente il contratto.

Poiché il contratto è experimental, la sua firma può cambiare in una release minor, preceduta da un avviso di deprecazione (la promessa sperimentale). Applicare un pin restrittivo o incapsularlo dietro un adapter proprio prima di farvi affidamento in produzione. Trattare il contratto di streaming come un punto di estensione in via di stabilizzazione, non come un contratto congelato.

In questa pagina non è presente alcuna API a runtime. La superficie rilevante è il tag PHPDoc @stability su ogni contratto pubblico e la contracts map rigenerata che aggrega la promessa di ogni contratto.

Leggere la stabilità di un contratto dal relativo sorgente prima di farvi affidamento.

<?php
declare(strict_types=1);
use ReflectionClass;
$doc = (new ReflectionClass(\NextPDF\Contracts\FontRegistryInterface::class))
->getDocComment();
// Look for the "@stability stable" line in the contract PHPDoc.
\assert(\is_string($doc) && \str_contains($doc, '@stability stable'));

Un vincolo di versione Composer blocca la versione major, che è l’unità di modifica incompatibile per un contratto stable.

{
"require": {
"nextpdf/core": "^3.0"
}
}

Usare il pin a ^3.0 per ricevere le release minor e patch senza alcuna modifica incompatibile a un contratto stable. Applicare un pin più restrittivo quando si dipende da un contratto experimental, perché un contratto experimental può cambiare in una release minor.

  • Tag, non visibilità. Un metodo PHP public non fa parte della service provider interface a meno che il tipo che lo dichiara non riporti un tag @stability.
  • Deriva sperimentale. Un contratto experimental può cambiare in una release minor. Applicare un pin restrittivo o incapsularlo dietro un adapter proprio. Questo vale per i contratti di streaming anche se dispongono di implementazioni distribuite.
  • Nuovi metodi predefiniti. Un’interfaccia stable può acquisire un metodo dotato di comportamento predefinito. Implementare il nuovo metodo al momento dell’aggiornamento per mantenere esplicita la propria implementazione.
  • Parità tra edizioni. NextPDF Pro e NextPDF Enterprise seguono le stesse regole. Un contratto a cui si fa riferimento in Core rimane valido rispetto a un’implementazione Premium dello stesso contratto.

Un contratto attraversa un ciclo di vita definito:

  1. Contrassegno. Il proprietario imposta @stability deprecated nel PHPDoc del sorgente e registra la sostituzione e la versione di rimozione.
  2. Avviso. La deprecazione viene annunciata nel changelog in corrispondenza della release che la contrassegna.
  3. Sovrapposizione. Il contratto deprecato e la relativa sostituzione coesistono per almeno una release minor.
  4. Rimozione. Il contratto viene rimosso nella release major indicata. La rimozione non avviene mai in una release minor o patch.

Pianificare un aggiornamento non appena un contratto viene contrassegnato come deprecated. La sostituzione è sempre indicata.

Questa pagina definisce una policy. Non comporta alcun costo a runtime.

I contratti di firma sono stable e seguono la promessa di interfaccia. Un nuovo metodo su un contratto di firma arriva solo con un comportamento predefinito oppure su un nuovo contratto, in modo che un’implementazione basata su hardware non si rompa durante un aggiornamento minor. Esaminare il changelog prima di un aggiornamento major, perché una versione major può modificare un contratto stable.

La regola di versionamento è conforme al Semantic Versioning 2.0.0. La generazione del changelog segue Conventional Commits 1.0.0.

NextPDF Pro e NextPDF Enterprise seguono le stesse regole di stabilità della service provider interface di Core. Un contratto a cui si fa riferimento in Core rimane valido rispetto all’implementazione Premium dello stesso contratto, perciò il codice dell’estensione è portabile tra le edizioni.

Il glossario definisce stability tag e backward-compatibility promise; per ciascuna definizione canonica consultare il glossario pubblicato.