Passa al contenuto principale

1. Introduction (Introduzione)

1.1. Overview (Panoramica)

Un Uniform Resource Identifier (URI) [RFC3986] è spesso utilizzato per identificare una risorsa specifica all'interno di uno spazio comune di risorse simili (informalmente, uno "spazio URI"). Ad esempio, gli spazi Web personali sono spesso delegati utilizzando un modello comune, come:

http://example.com/~fred/
http://example.com/~mark/

oppure un insieme di voci di dizionario potrebbe essere raggruppato in una gerarchia in base alla prima lettera del termine, come in:

http://example.com/dictionary/c/cat
http://example.com/dictionary/d/dog

oppure un'interfaccia di servizio potrebbe essere invocata con vari input utente in un modello comune, come in:

http://example.com/search?q=cat&lang=en
http://example.com/search?q=chien&lang=fr

Un modello URI (URI Template) è una sequenza compatta di caratteri per descrivere un insieme di Uniform Resource Identifiers attraverso l'espansione di variabili (Variable Expansion).

I modelli URI forniscono un meccanismo per astrarre uno spazio di identificatori di risorse in modo che le parti variabili possano essere facilmente identificate e descritte. I modelli URI possono avere molti usi, tra cui la scoperta di servizi disponibili, la configurazione di mappature di risorse, la definizione di collegamenti calcolati, la specifica di interfacce e altre forme di interazione programmatica con le risorse. Ad esempio, le risorse sopra indicate potrebbero essere descritte dai seguenti modelli URI:

http://example.com/~{username}/
http://example.com/dictionary/{term:1}/{term}
http://example.com/search{?q,lang}

Definiamo i seguenti termini:

expression (espressione): Il testo tra ' e ', incluse le parentesi graffe che lo racchiudono, come definito nella Sezione 2.

expansion (espansione): Il risultato stringa ottenuto da un'espressione di modello dopo averla elaborata in base al suo tipo di espressione, all'elenco dei nomi delle variabili e ai modificatori di valore, come definito nella Sezione 3.

template processor (processore di modelli): Un programma o una libreria che, dato un modello URI e un insieme di variabili con valori, trasforma la stringa del modello in un riferimento URI analizzando il modello per le espressioni e sostituendo ciascuna con la sua corrispondente espansione.

Un modello URI fornisce sia una descrizione strutturale di uno spazio URI sia, quando vengono forniti valori delle variabili, istruzioni leggibili dalla macchina su come costruire un URI corrispondente a quei valori. Un modello URI viene trasformato in un riferimento URI sostituendo ogni espressione delimitata con il suo valore come definito dal tipo di espressione e dai valori delle variabili nominate nell'espressione. I tipi di espressione vanno dalla semplice espansione di stringa a elenchi multipli name=value. Le espansioni si basano sulla sintassi generica URI, consentendo a un'implementazione di elaborare qualsiasi modello URI senza conoscere i requisiti specifici dello schema di ogni possibile URI risultante.

Ad esempio, il seguente modello URI include un'espressione di parametro in stile modulo (Form-Style Parameter Expression), come indicato dall'operatore "?" che appare prima dei nomi delle variabili:

http://www.example.com/foo{?query,number}

Il processo di espansione per le espressioni che iniziano con l'operatore punto interrogativo ("?") segue lo stesso schema delle interfacce in stile modulo sul World Wide Web:

http://www.example.com/foo{?query,number}
\_____________/
|
|
Per ogni variabile definita in [ 'query', 'number' ],
sostituire "?" se è la prima sostituzione o "&"
successivamente, seguito dal nome della variabile, '=' e dal
valore della variabile.

Se le variabili hanno i valori:

query  := "mycelium"
number := 100

allora l'espansione del modello URI sopra è:

http://www.example.com/foo?query=mycelium&number=100

In alternativa, se 'query' non è definito, allora l'espansione sarebbe:

http://www.example.com/foo?number=100

oppure se entrambe le variabili non sono definite, sarebbe:

http://www.example.com/foo

Un modello URI può essere fornito in forma assoluta, come negli esempi sopra, o in forma relativa. Un modello viene espanso prima che il riferimento risultante venga risolto da forma relativa a forma assoluta.

Sebbene la sintassi URI sia utilizzata per il risultato, la stringa del modello può contenere l'insieme più ampio di caratteri che si possono trovare nei riferimenti Internationalized Resource Identifier (IRI) [RFC3987]. Pertanto, un modello URI è anche un modello IRI e il risultato dell'elaborazione del modello può essere trasformato in un IRI seguendo il processo definito nella Sezione 3.2 di [RFC3987].

1.2. Levels and Expression Types (Livelli e tipi di espressione)

I modelli URI sono simili a un linguaggio di macro con un insieme fisso di definizioni di macro: il tipo di espressione (Expression Type) determina il processo di espansione. Il tipo di espressione predefinito è l'espansione di stringa semplice (Simple String Expansion), in cui una singola variabile nominata viene sostituita dal suo valore come stringa dopo la codifica percentuale (Percent-Encoding) di tutti i caratteri che non fanno parte dell'insieme di caratteri URI non riservati (Unreserved URI Characters) (Sezione 1.5).

Poiché la maggior parte dei processori di modelli implementati prima di questa specifica hanno implementato solo il tipo di espressione predefinito, ci riferiamo a questi come modelli Level 1.

.-----------------------------------------------------------------.
| Esempi Level 1, con valori di variabili: |
| |
| var := "value" |
| hello := "Hello World!" |
| |
|-----------------------------------------------------------------|
| Op Espressione Espansione |
|-----------------------------------------------------------------|
| | Espansione di stringa semplice (Sez 3.2.2) |
| | |
| | `{var}` value |
| | {hello} Hello%20World%21 |
'-----------------------------------------------------------------'

I modelli Level 2 aggiungono l'operatore più ("+") per l'espansione di valori che possono includere caratteri URI riservati (Reserved URI Characters) (Sezione 1.5), e l'operatore cancelletto ("#") per l'espansione di identificatori di frammento (Fragment Identifiers).

.-----------------------------------------------------------------.
| Esempi Level 2, con valori di variabili: |
| |
| var := "value" |
| hello := "Hello World!" |
| path := "/foo/bar" |
| |
|-----------------------------------------------------------------|
| Op Espressione Espansione |
|-----------------------------------------------------------------|
| + | Espansione di stringa riservata (Sez 3.2.3) |
| | |
| | {+var} value |
| | {+hello} Hello%20World! |
| | {+path}/here /foo/bar/here |
| | here?ref={+path} here?ref=/foo/bar |
|-----+-----------------------------------------------------------|
| # | Espansione di frammento, prefisso cancelletto (Sez 3.2.4) |
| | |
| | X{#var} X#value |
| | X{#hello} X#Hello%20World! |
'-----------------------------------------------------------------'

I modelli Level 3 consentono più variabili per espressione, ciascuna separata da una virgola, e aggiungono operatori più complessi per etichette con prefisso punto (Dot-Prefixed Labels), segmenti di percorso con prefisso barra (Slash-Prefixed Path Segments), parametri di percorso con prefisso punto e virgola (Semicolon-Prefixed Path Parameters) e la costruzione in stile modulo (Form-Style Construction) di una sintassi di query composta da coppie name=value separate da un carattere e commerciale.

.-----------------------------------------------------------------.
| Esempi Level 3, con valori di variabili: |
| |
| var := "value" |
| hello := "Hello World!" |
| empty := "" |
| path := "/foo/bar" |
| x := "1024" |
| y := "768" |
| |
|-----------------------------------------------------------------|
| Op Espressione Espansione |
|-----------------------------------------------------------------|
| | Espansione di stringa con più variabili (Sez 3.2.2) |
| | |
| | map?{x,y} map?1024,768 |
| | {x,hello,y} 1024,Hello%20World%21,768 |
| | |
|-----+-----------------------------------------------------------|
| + | Espansione riservata con più variabili (Sez 3.2.3) |
| | |
| | {+x,hello,y} 1024,Hello%20World!,768 |
| | {+path,x}/here /foo/bar,1024/here |
| | |
|-----+-----------------------------------------------------------|
| # | Espansione di frammento con più variabili (Sez 3.2.4) |
| | |
| | {#x,hello,y} #1024,Hello%20World!,768 |
| | {#path,x}/here #/foo/bar,1024/here |
| | |
|-----+-----------------------------------------------------------|
| . | Espansione di etichetta, prefisso punto (Sez 3.2.5) |
| | |
| | X{.var} X.value |
| | X{.x,y} X.1024.768 |
| | |
|-----+-----------------------------------------------------------|
| / | Segmenti di percorso, prefisso barra (Sez 3.2.6) |
| | |
| | {/var} /value |
| | {/var,x}/here /value/1024/here |
| | |
|-----+-----------------------------------------------------------|
| ; | Parametri stile percorso, prefisso punto e vir(Sez 3.2.7) |
| | |
| | {;x,y} ;x=1024;y=768 |
| | {;x,y,empty} ;x=1024;y=768;empty |
| | |
|-----+-----------------------------------------------------------|
| ? | Query stile modulo, separata da e commerciale (Sez 3.2.8) |
| | |
| | {?x,y} ?x=1024&y=768 |
| | {?x,y,empty} ?x=1024&y=768&empty= |
| | |
|-----+-----------------------------------------------------------|
| & | Continuazione query stile modulo (Sez 3.2.9) |
| | |
| | ?fixed=yes{&x} ?fixed=yes&x=1024 |
| | {&x,y,empty} &x=1024&y=768&empty= |
| | |
'-----------------------------------------------------------------'

Infine, i modelli Level 4 aggiungono modificatori di valore (Value Modifiers) come suffisso opzionale a ciascun nome di variabile. Un modificatore di prefisso (Prefix Modifier) (":") indica che solo un numero limitato di caratteri dall'inizio del valore viene utilizzato dall'espansione (Sezione 2.4.1). Un modificatore di esplosione (Explode Modifier) ("*") indica che la variabile deve essere trattata come un valore composito (Composite Value), costituito da un elenco di nomi o da un array associativo di coppie (name, value), che viene espanso come se ogni membro fosse una variabile separata (Sezione 2.4.2).

.-----------------------------------------------------------------.
| Esempi Level 4, con valori di variabili: |
| |
| var := "value" |
| hello := "Hello World!" |
| path := "/foo/bar" |
| list := ("red", "green", "blue") |
| keys := [("semi",";"),("dot","."),("comma",",")] |
| |
| Op Espressione Espansione |
|-----------------------------------------------------------------|
| | Espansione di stringa con modificatori (Sez 3.2.2) |
| | |
| | {var:3} val |
| | {var:30} value |
| | {list} red,green,blue |
| | {list*} red,green,blue |
| | {keys} semi,%3B,dot,.,comma,%2C |
| | {keys*} semi=%3B,dot=.,comma=%2C |
| | |
|-----+-----------------------------------------------------------|
| + | Espansione riservata con modificatori (Sez 3.2.3) |
| | |
| | {+path:6}/here /foo/b/here |
| | {+list} red,green,blue |
| | {+list*} red,green,blue |
| | {+keys} semi,;,dot,.,comma,, |
| | {+keys*} semi=;,dot=.,comma=, |
| | |
|-----+-----------------------------------------------------------|
| # | Espansione di frammento con modificatori (Sez 3.2.4) |
| | |
| | {#path:6}/here #/foo/b/here |
| | {#list} #red,green,blue |
| | {#list*} #red,green,blue |
| | {#keys} #semi,;,dot,.,comma,, |
| | {#keys*} #semi=;,dot=.,comma=, |
| | |
|-----+-----------------------------------------------------------|
| . | Espansione di etichetta, prefisso punto (Sez 3.2.5) |
| | |
| | X{.var:3} X.val |
| | X{.list} X.red,green,blue |
| | X{.list*} X.red.green.blue |
| | X{.keys} X.semi,%3B,dot,.,comma,%2C |
| | X{.keys*} X.semi=%3B.dot=..comma=%2C |
| | |
|-----+-----------------------------------------------------------|
| / | Segmenti di percorso, prefisso barra (Sez 3.2.6) |
| | |
| | {/var:1,var} /v/value |
| | {/list} /red,green,blue |
| | {/list*} /red/green/blue |
| | {/list*,path:4} /red/green/blue/%2Ffoo |
| | {/keys} /semi,%3B,dot,.,comma,%2C |
| | {/keys*} /semi=%3B/dot=./comma=%2C |
| | |
|-----+-----------------------------------------------------------|
| ; | Parametri stile percorso, prefisso punto e vir(Sez 3.2.7) |
| | |
| | {;hello:5} ;hello=Hello |
| | {;list} ;list=red,green,blue |
| | {;list*} ;list=red;list=green;list=blue |
| | {;keys} ;keys=semi,%3B,dot,.,comma,%2C |
| | {;keys*} ;semi=%3B;dot=.;comma=%2C |
| | |
|-----+-----------------------------------------------------------|
| ? | Query stile modulo, separata da e commerciale (Sez 3.2.8) |
| | |
| | {?var:3} ?var=val |
| | {?list} ?list=red,green,blue |
| | {?list*} ?list=red&list=green&list=blue |
| | {?keys} ?keys=semi,%3B,dot,.,comma,%2C |
| | {?keys*} ?semi=%3B&dot=.&comma=%2C |
| | |
|-----+-----------------------------------------------------------|
| & | Continuazione query stile modulo (Sez 3.2.9) |
| | |
| | {&var:3} &var=val |
| | {&list} &list=red,green,blue |
| | {&list*} &list=red&list=green&list=blue |
| | {&keys} &keys=semi,%3B,dot,.,comma,%2C |
| | {&keys*} &semi=%3B&dot=.&comma=%2C |
| | |
'-----------------------------------------------------------------'

1.3. Design Considerations (Considerazioni di progettazione)

Meccanismi simili ai modelli URI sono stati definiti all'interno di diverse specifiche, tra cui WSDL [WSDL], WADL [WADL] e OpenSearch [OpenSearch]. Questa specifica estende e definisce formalmente la sintassi in modo che i modelli URI possano essere utilizzati in modo coerente attraverso più applicazioni Internet e all'interno dei campi dei messaggi Internet, mantenendo al contempo la compatibilità con quelle definizioni precedenti.

La sintassi dei modelli URI è stata progettata per bilanciare attentamente la necessità di un potente meccanismo di espansione con la necessità di facilità di implementazione. La sintassi è progettata per essere banale da analizzare pur fornendo abbastanza flessibilità per esprimere molti scenari di modello comuni. Le implementazioni sono in grado di analizzare il modello ed eseguire le espansioni in un singolo passaggio.

I modelli sono semplici e leggibili quando utilizzati con esempi comuni perché gli operatori a carattere singolo corrispondono ai delimitatori della sintassi generica URI. Il delimitatore associato all'operatore (".", ";", "/", "?", "&" e "#") viene omesso quando nessuna delle variabili elencate è definita. Allo stesso modo, il processo di espansione per ";" (parametri in stile percorso) ometterà il "=" quando il valore della variabile è vuoto, mentre il processo per "?" (parametri in stile modulo) non ometterà il "=" quando il valore è vuoto. Le variabili multiple e i valori di lista hanno i loro valori uniti con "," se non esiste un meccanismo di unione predefinito per l'operatore. Gli operatori "+" e "#" sostituiranno i caratteri riservati non codificati trovati all'interno dei valori delle variabili; gli altri operatori eseguiranno la codifica percentuale dei caratteri riservati trovati nei valori delle variabili prima dell'espansione.

I casi più comuni per gli spazi URI possono essere descritti con espressioni di modello Level 1. Se fossimo preoccupati solo della generazione di URI, allora la sintassi del modello potrebbe essere limitata alla semplice espansione di variabili, poiché forme più complesse potrebbero essere generate modificando i valori delle variabili. Tuttavia, i modelli URI hanno l'obiettivo aggiuntivo di descrivere il layout degli identificatori in termini di valori di dati preesistenti. Pertanto, la sintassi del modello include operatori che riflettono come gli identificatori di risorse sono comunemente allocati. Allo stesso modo, poiché le sottostringhe di prefisso sono spesso utilizzate per partizionare grandi spazi di risorse, i modificatori sui valori delle variabili forniscono un modo per specificare sia la sottostringa che la stringa del valore completo con un singolo nome di variabile.

1.4. Limitations (Limitazioni)

Poiché un modello URI descrive un sovrainsieme (Superset) degli identificatori, non vi è alcuna implicazione che ogni possibile espansione per ogni espressione di variabile delimitata corrisponda a un URI di una risorsa esistente. La nostra aspettativa è che un'applicazione che costruisce URI secondo il modello riceverà un insieme appropriato di valori per le variabili sostituite, o almeno un mezzo per convalidare l'immissione di dati utente per quei valori.

I modelli URI non sono URI: non identificano una risorsa astratta o fisica, non vengono analizzati come URI e non dovrebbero (should) essere utilizzati in luoghi dove ci si aspetta un URI a meno che le espressioni del modello non vengano espanse da un processore di modelli prima dell'uso. Nomi di campo, elemento o attributo distinti dovrebbero essere utilizzati per differenziare gli elementi di protocollo che trasportano un modello URI da quelli che si aspettano un riferimento URI.

Alcuni modelli URI possono essere utilizzati al contrario per scopi di corrispondenza di variabili (Variable Matching): confrontare il modello con un URI completamente formato per estrarre le parti variabili da quell'URI e assegnarle alle variabili nominate. La corrispondenza di variabili funziona bene solo se le espressioni del modello sono delimitate dall'inizio o dalla fine dell'URI o da caratteri che non possono far parte dell'espansione, come i caratteri riservati che circondano un'espressione di stringa semplice. In generale, i linguaggi di espressioni regolari sono più adatti per la corrispondenza di variabili.

1.5. Notational Conventions (Convenzioni notazionali)

Le parole chiave "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY" e "OPTIONAL" in questo documento devono essere interpretate come descritto in [RFC2119].

Questa specifica utilizza la notazione ABNF (Augmented Backus-Naur Form, forma di Backus-Naur aumentata) di [RFC5234]. Le seguenti regole ABNF sono importate dai riferimenti normativi [RFC5234], [RFC3986] e [RFC3987].

ALPHA          =  %x41-5A / %x61-7A   ; A-Z / a-z
DIGIT = %x30-39 ; 0-9
HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F"
; non sensibile alle maiuscole

pct-encoded = "%" HEXDIG HEXDIG
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
reserved = gen-delims / sub-delims
gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
/ "*" / "+" / "," / ";" / "="

ucschar = %xA0-D7FF / %xF900-FDCF / %xFDF0-FFEF
/ %x10000-1FFFD / %x20000-2FFFD / %x30000-3FFFD
/ %x40000-4FFFD / %x50000-5FFFD / %x60000-6FFFD
/ %x70000-7FFFD / %x80000-8FFFD / %x90000-9FFFD
/ %xA0000-AFFFD / %xB0000-BFFFD / %xC0000-CFFFD
/ %xD0000-DFFFD / %xE1000-EFFFD

iprivate = %xE000-F8FF / %xF0000-FFFFD / %x100000-10FFFD

1.6. Character Encoding and Unicode Normalization (Codifica dei caratteri e normalizzazione Unicode)

Questa specifica utilizza i termini "character (carattere)", "character encoding scheme (schema di codifica dei caratteri)", "code point (punto di codice)", "coded character set (set di caratteri codificato)", "glyph (glifo)", "non-ASCII", "normalization (normalizzazione)", "protocol element (elemento di protocollo)" e "regular expression (espressione regolare)" come sono definiti in [RFC6365].

La notazione ABNF definisce i suoi valori terminali come interi non negativi (punti di codice) che sono un sovrainsieme del set di caratteri codificato US-ASCII [ASCII]. Questa specifica definisce i valori terminali come punti di codice all'interno del set di caratteri codificato Unicode [UNIV6].

Nonostante la sintassi e il processo di espansione del modello siano definiti in termini di punti di codice Unicode, si deve comprendere che i modelli si presentano in pratica come una sequenza di caratteri in qualsiasi forma o codifica sia appropriata al contesto in cui si verificano, siano essi ottetti incorporati in un elemento di protocollo di rete o glifi dipinti sul lato di un autobus. Questa specifica non impone alcuno schema di codifica dei caratteri particolare per la mappatura tra i caratteri del modello URI e gli ottetti utilizzati per memorizzare o trasmettere tali caratteri. Quando un modello URI appare in un elemento di protocollo, lo schema di codifica dei caratteri è definito da quel protocollo; senza tale definizione, si presume che un modello URI sia nello stesso schema di codifica dei caratteri del testo circostante. È solo durante il processo di espansione del modello che una stringa di caratteri in un modello URI è RICHIESTA (REQUIRED) per essere elaborata come una sequenza di punti di codice Unicode.

Lo standard Unicode [UNIV6] definisce varie equivalenze tra sequenze di caratteri per vari scopi. L'allegato #15 dello standard Unicode [UTR15] definisce varie forme di normalizzazione (Normalization Forms) per queste equivalenze. La forma di normalizzazione determina come codificare in modo coerente stringhe equivalenti. In teoria, tutte le implementazioni di elaborazione URI, compresi i processori di modelli, dovrebbero utilizzare la stessa forma di normalizzazione per generare un riferimento URI. In pratica, non lo fanno. Se un valore è stato fornito dallo stesso server della risorsa, si può presumere che la stringa sia già nella forma attesa da quel server. Se un valore è fornito da un utente, ad esempio tramite una finestra di dialogo di immissione dati, la stringa DOVREBBE (SHOULD) essere normalizzata come forma di normalizzazione C (NFC: Canonical Decomposition, followed by Canonical Composition, decomposizione canonica seguita da composizione canonica) prima di essere utilizzata nelle espansioni da un processore di modelli.

Allo stesso modo, quando i dati non-ASCII che rappresentano stringhe leggibili vengono codificati in percentuale per l'uso in un riferimento URI, un processore di modelli DEVE (MUST) prima codificare la stringa come UTF-8 [RFC3629] e quindi codificare in percentuale tutti gli ottetti che non sono consentiti in un riferimento URI.