Aller au contenu principal

1. Introduction

1.1. Overview (Vue d'ensemble)

Un identificateur de ressource uniforme (Uniform Resource Identifier, URI) [RFC3986] est souvent utilisé pour identifier une ressource spécifique dans un espace commun de ressources similaires (de manière informelle, un « espace URI »). Par exemple, les espaces Web personnels sont souvent délégués en utilisant un modèle commun, tel que :

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

ou un ensemble d'entrées de dictionnaire peut être regroupé dans une hiérarchie par la première lettre du terme, comme dans :

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

ou une interface de service peut être invoquée avec diverses entrées utilisateur dans un modèle commun, comme dans :

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

Un modèle d'URI (URI Template) est une séquence compacte de caractères permettant de décrire une plage d'identificateurs de ressources uniformes par l'expansion de variables (Variable Expansion).

Les modèles d'URI fournissent un mécanisme pour abstraire un espace d'identificateurs de ressources de sorte que les parties variables puissent être facilement identifiées et décrites. Les modèles d'URI peuvent avoir de nombreuses utilisations, notamment la découverte de services disponibles, la configuration de mappages de ressources, la définition de liens calculés, la spécification d'interfaces et d'autres formes d'interaction programmatique avec les ressources. Par exemple, les ressources ci-dessus pourraient être décrites par les modèles d'URI suivants :

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

Nous définissons les termes suivants :

expression : Le texte entre ' et ', y compris les accolades englobantes, tel que défini dans la section 2.

expansion : Le résultat sous forme de chaîne obtenu à partir d'une expression de modèle après l'avoir traitée selon son type d'expression, sa liste de noms de variables et ses modificateurs de valeur, tel que défini dans la section 3.

template processor (processeur de modèle) : Un programme ou une bibliothèque qui, étant donné un modèle d'URI et un ensemble de variables avec des valeurs, transforme la chaîne de modèle en une référence URI en analysant le modèle pour les expressions et en substituant chacune par son expansion correspondante.

Un modèle d'URI fournit à la fois une description structurelle d'un espace URI et, lorsque des valeurs de variables sont fournies, des instructions lisibles par machine sur la façon de construire un URI correspondant à ces valeurs. Un modèle d'URI est transformé en référence URI en remplaçant chaque expression délimitée par sa valeur telle que définie par le type d'expression et les valeurs des variables nommées dans l'expression. Les types d'expressions vont de l'expansion de chaîne simple aux listes multiples name=value. Les expansions sont basées sur la syntaxe générique URI, permettant à une implémentation de traiter n'importe quel modèle d'URI sans connaître les exigences spécifiques au schéma de chaque URI résultant possible.

Par exemple, le modèle d'URI suivant inclut une expression de paramètre de style formulaire (Form-Style Parameter Expression), comme indiqué par l'opérateur "?" apparaissant avant les noms de variables :

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

Le processus d'expansion pour les expressions commençant par l'opérateur point d'interrogation ("?") suit le même modèle que les interfaces de style formulaire sur le World Wide Web :

http://www.example.com/foo{?query,number}
\_____________/
|
|
Pour chaque variable définie dans [ 'query', 'number' ],
substituer "?" s'il s'agit de la première substitution ou "&"
par la suite, suivi du nom de la variable, '=', et de la
valeur de la variable.

Si les variables ont les valeurs :

query  := "mycelium"
number := 100

alors l'expansion du modèle d'URI ci-dessus est :

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

Alternativement, si 'query' est indéfini, alors l'expansion serait :

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

ou si les deux variables sont indéfinies, alors ce serait :

http://www.example.com/foo

Un modèle d'URI peut être fourni sous forme absolue, comme dans les exemples ci-dessus, ou sous forme relative. Un modèle est expansé avant que la référence résultante ne soit résolue de forme relative à forme absolue.

Bien que la syntaxe URI soit utilisée pour le résultat, la chaîne de modèle est autorisée à contenir l'ensemble plus large de caractères que l'on peut trouver dans les références d'identificateurs de ressources internationalisés (Internationalized Resource Identifier, IRI) [RFC3987]. Par conséquent, un modèle d'URI est également un modèle IRI, et le résultat du traitement du modèle peut être transformé en IRI en suivant le processus défini dans la section 3.2 de [RFC3987].

1.2. Levels and Expression Types (Niveaux et types d'expressions)

Les modèles d'URI sont similaires à un langage de macros avec un ensemble fixe de définitions de macros : le type d'expression (Expression Type) détermine le processus d'expansion. Le type d'expression par défaut est l'expansion de chaîne simple (Simple String Expansion), dans laquelle une seule variable nommée est remplacée par sa valeur sous forme de chaîne après encodage en pourcentage (Percent-Encoding) de tous les caractères qui ne font pas partie de l'ensemble des caractères URI non réservés (Unreserved URI Characters) (Section 1.5).

Étant donné que la plupart des processeurs de modèles implémentés avant cette spécification n'ont implémenté que le type d'expression par défaut, nous les appelons modèles Level 1.

.-----------------------------------------------------------------.
| Exemples Level 1, avec les valeurs de variables : |
| |
| var := "value" |
| hello := "Hello World!" |
| |
|-----------------------------------------------------------------|
| Op Expression Expansion |
|-----------------------------------------------------------------|
| | Expansion de chaîne simple (Sec 3.2.2) |
| | |
| | {var} value |
| | {hello} Hello%20World%21 |
'-----------------------------------------------------------------'

Les modèles Level 2 ajoutent l'opérateur plus ("+") pour l'expansion de valeurs autorisées à inclure des caractères URI réservés (Reserved URI Characters) (Section 1.5), et l'opérateur dièse ("#") pour l'expansion d'identificateurs de fragment (Fragment Identifiers).

.-----------------------------------------------------------------.
| Exemples Level 2, avec les valeurs de variables : |
| |
| var := "value" |
| hello := "Hello World!" |
| path := "/foo/bar" |
| |
|-----------------------------------------------------------------|
| Op Expression Expansion |
|-----------------------------------------------------------------|
| + | Expansion de chaîne réservée (Sec 3.2.3) |
| | |
| | {+var} value |
| | {+hello} Hello%20World! |
| | {+path}/here /foo/bar/here |
| | here?ref={+path} here?ref=/foo/bar |
|-----+-----------------------------------------------------------|
| # | Expansion de fragment, préfixe dièse (Sec 3.2.4) |
| | |
| | X{#var} X#value |
| | X{#hello} X#Hello%20World! |
'-----------------------------------------------------------------'

Les modèles Level 3 permettent plusieurs variables par expression, chacune séparée par une virgule, et ajoutent des opérateurs plus complexes pour les étiquettes préfixées par un point (Dot-Prefixed Labels), les segments de chemin préfixés par une barre oblique (Slash-Prefixed Path Segments), les paramètres de chemin préfixés par un point-virgule (Semicolon-Prefixed Path Parameters), et la construction de style formulaire (Form-Style Construction) d'une syntaxe de requête composée de paires name=value séparées par un caractère esperluette.

.-----------------------------------------------------------------.
| Exemples Level 3, avec les valeurs de variables : |
| |
| var := "value" |
| hello := "Hello World!" |
| empty := "" |
| path := "/foo/bar" |
| x := "1024" |
| y := "768" |
| |
|-----------------------------------------------------------------|
| Op Expression Expansion |
|-----------------------------------------------------------------|
| | Expansion de chaîne avec plusieurs variables (Sec 3.2.2) |
| | |
| | map?{x,y} map?1024,768 |
| | {x,hello,y} 1024,Hello%20World%21,768 |
| | |
|-----+-----------------------------------------------------------|
| + | Expansion réservée avec plusieurs variables (Sec 3.2.3) |
| | |
| | {+x,hello,y} 1024,Hello%20World!,768 |
| | {+path,x}/here /foo/bar,1024/here |
| | |
|-----+-----------------------------------------------------------|
| # | Expansion de fragment avec plusieurs var. (Sec 3.2.4) |
| | |
| | {#x,hello,y} #1024,Hello%20World!,768 |
| | {#path,x}/here #/foo/bar,1024/here |
| | |
|-----+-----------------------------------------------------------|
| . | Expansion d'étiquette, préfixe point (Sec 3.2.5) |
| | |
| | X{.var} X.value |
| | X{.x,y} X.1024.768 |
| | |
|-----+-----------------------------------------------------------|
| / | Segments de chemin, préfixe barre oblique (Sec 3.2.6) |
| | |
| | {/var} /value |
| | {/var,x}/here /value/1024/here |
| | |
|-----+-----------------------------------------------------------|
| ; | Paramètres de style chemin, préfixe point-vir (Sec 3.2.7) |
| | |
| | {;x,y} ;x=1024;y=768 |
| | {;x,y,empty} ;x=1024;y=768;empty |
| | |
|-----+-----------------------------------------------------------|
| ? | Requête de style formulaire, séparée esperluet (Sec 3.2.8)|
| | |
| | {?x,y} ?x=1024&y=768 |
| | {?x,y,empty} ?x=1024&y=768&empty= |
| | |
|-----+-----------------------------------------------------------|
| & | Continuation de requête de style formulaire (Sec 3.2.9) |
| | |
| | ?fixed=yes{&x} ?fixed=yes&x=1024 |
| | {&x,y,empty} &x=1024&y=768&empty= |
| | |
'-----------------------------------------------------------------'

Enfin, les modèles Level 4 ajoutent des modificateurs de valeur (Value Modifiers) comme suffixe optionnel à chaque nom de variable. Un modificateur de préfixe (Prefix Modifier) (":") indique que seul un nombre limité de caractères depuis le début de la valeur sont utilisés par l'expansion (Section 2.4.1). Un modificateur d'explosion (Explode Modifier) ("*") indique que la variable doit être traitée comme une valeur composite (Composite Value), composée soit d'une liste de noms, soit d'un tableau associatif de paires (name, value), qui est expansée comme si chaque membre était une variable distincte (Section 2.4.2).

.-----------------------------------------------------------------.
| Exemples Level 4, avec les valeurs de variables : |
| |
| var := "value" |
| hello := "Hello World!" |
| path := "/foo/bar" |
| list := ("red", "green", "blue") |
| keys := [("semi",";"),("dot","."),("comma",",")] |
| |
| Op Expression Expansion |
|-----------------------------------------------------------------|
| | Expansion de chaîne avec modificateurs (Sec 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 |
| | |
|-----+-----------------------------------------------------------|
| + | Expansion réservée avec modificateurs (Sec 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=, |
| | |
|-----+-----------------------------------------------------------|
| # | Expansion de fragment avec modificateurs (Sec 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=, |
| | |
|-----+-----------------------------------------------------------|
| . | Expansion d'étiquette, préfixe point (Sec 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 |
| | |
|-----+-----------------------------------------------------------|
| / | Segments de chemin, préfixe barre oblique (Sec 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 |
| | |
|-----+-----------------------------------------------------------|
| ; | Paramètres de style chemin, préfixe point-vir (Sec 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 |
| | |
|-----+-----------------------------------------------------------|
| ? | Requête de style formulaire, séparée esperluet (Sec 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 |
| | |
|-----+-----------------------------------------------------------|
| & | Continuation de requête de style formulaire (Sec 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 (Considérations de conception)

Des mécanismes similaires aux modèles d'URI ont été définis dans plusieurs spécifications, notamment WSDL [WSDL], WADL [WADL] et OpenSearch [OpenSearch]. Cette spécification étend et définit formellement la syntaxe afin que les modèles d'URI puissent être utilisés de manière cohérente dans plusieurs applications Internet et dans les champs de messages Internet, tout en conservant la compatibilité avec ces définitions antérieures.

La syntaxe des modèles d'URI a été conçue pour équilibrer soigneusement le besoin d'un mécanisme d'expansion puissant avec le besoin de facilité de mise en œuvre. La syntaxe est conçue pour être triviale à analyser tout en offrant suffisamment de flexibilité pour exprimer de nombreux scénarios de modèles courants. Les implémentations sont capables d'analyser le modèle et d'effectuer les expansions en un seul passage.

Les modèles sont simples et lisibles lorsqu'ils sont utilisés avec des exemples courants car les opérateurs à un seul caractère correspondent aux délimiteurs de syntaxe générique URI. Le délimiteur associé à l'opérateur (".", ";", "/", "?", "&" et "#") est omis lorsqu'aucune des variables listées n'est définie. De même, le processus d'expansion pour ";" (paramètres de style chemin) omettra le "=" lorsque la valeur de la variable est vide, tandis que le processus pour "?" (paramètres de style formulaire) n'omettra pas le "=" lorsque la valeur est vide. Les variables multiples et les valeurs de liste ont leurs valeurs jointes avec "," s'il n'y a pas de mécanisme de jonction prédéfini pour l'opérateur. Les opérateurs "+" et "#" substitueront les caractères réservés non encodés trouvés dans les valeurs des variables ; les autres opérateurs effectueront un encodage en pourcentage des caractères réservés trouvés dans les valeurs des variables avant l'expansion.

Les cas les plus courants pour les espaces URI peuvent être décrits avec des expressions de modèle Level 1. Si nous n'étions préoccupés que par la génération d'URI, la syntaxe du modèle pourrait être limitée à une simple expansion de variables, puisque des formes plus complexes pourraient être générées en modifiant les valeurs des variables. Cependant, les modèles d'URI ont l'objectif supplémentaire de décrire la disposition des identificateurs en termes de valeurs de données préexistantes. Par conséquent, la syntaxe du modèle inclut des opérateurs qui reflètent la manière dont les identificateurs de ressources sont généralement alloués. De même, étant donné que les sous-chaînes de préfixe sont souvent utilisées pour partitionner de grands espaces de ressources, les modificateurs sur les valeurs de variables fournissent un moyen de spécifier à la fois la sous-chaîne et la chaîne de valeur complète avec un seul nom de variable.

1.4. Limitations

Étant donné qu'un modèle d'URI décrit un sur-ensemble (Superset) des identificateurs, il n'y a aucune implication que chaque expansion possible pour chaque expression de variable délimitée corresponde à un URI d'une ressource existante. Notre attente est qu'une application construisant des URI selon le modèle se verra fournir un ensemble approprié de valeurs pour les variables substituées, ou au moins un moyen de valider la saisie de données utilisateur pour ces valeurs.

Les modèles d'URI ne sont pas des URI : ils n'identifient pas une ressource abstraite ou physique, ils ne sont pas analysés comme des URI, et ils ne devraient pas être utilisés dans des endroits où un URI serait attendu à moins que les expressions de modèle ne soient expansées par un processeur de modèle avant utilisation. Des noms de champ, d'élément ou d'attribut distincts devraient (should) être utilisés pour différencier les éléments de protocole qui portent un modèle d'URI de ceux qui attendent une référence URI.

Certains modèles d'URI peuvent être utilisés en sens inverse à des fins de correspondance de variables (Variable Matching) : comparer le modèle à un URI entièrement formé afin d'extraire les parties variables de cet URI et de les affecter aux variables nommées. La correspondance de variables ne fonctionne bien que si les expressions de modèle sont délimitées par le début ou la fin de l'URI ou par des caractères qui ne peuvent pas faire partie de l'expansion, tels que les caractères réservés entourant une expression de chaîne simple. En général, les langages d'expressions régulières sont mieux adaptés à la correspondance de variables.

1.5. Notational Conventions (Conventions de notation)

Les mots-clés "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY" et "OPTIONAL" dans ce document doivent être interprétés comme décrits dans [RFC2119].

Cette spécification utilise la notation de forme de Backus-Naur augmentée (Augmented Backus-Naur Form, ABNF) de [RFC5234]. Les règles ABNF suivantes sont importées des références normatives [RFC5234], [RFC3986] et [RFC3987].

ALPHA          =  %x41-5A / %x61-7A   ; A-Z / a-z
DIGIT = %x30-39 ; 0-9
HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F"
; insensible à la casse

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 (Encodage des caractères et normalisation Unicode)

Cette spécification utilise les termes "character (caractère)", "character encoding scheme (schéma d'encodage de caractères)", "code point (point de code)", "coded character set (jeu de caractères codé)", "glyph (glyphe)", "non-ASCII", "normalization (normalisation)", "protocol element (élément de protocole)" et "regular expression (expression régulière)" tels qu'ils sont définis dans [RFC6365].

La notation ABNF définit ses valeurs terminales comme étant des entiers non négatifs (points de code) qui sont un sur-ensemble du jeu de caractères codé US-ASCII [ASCII]. Cette spécification définit les valeurs terminales comme des points de code dans le jeu de caractères codé Unicode [UNIV6].

Bien que la syntaxe et le processus d'expansion de modèle soient définis en termes de points de code Unicode, il faut comprendre que les modèles se présentent en pratique sous forme de séquence de caractères dans n'importe quelle forme ou encodage approprié au contexte dans lequel ils se produisent, qu'il s'agisse d'octets incorporés dans un élément de protocole réseau ou de glyphes peints sur le côté d'un bus. Cette spécification n'impose aucun schéma d'encodage de caractères particulier pour mapper entre les caractères de modèle d'URI et les octets utilisés pour stocker ou transmettre ces caractères. Lorsqu'un modèle d'URI apparaît dans un élément de protocole, le schéma d'encodage de caractères est défini par ce protocole ; sans une telle définition, un modèle d'URI est supposé être dans le même schéma d'encodage de caractères que le texte environnant. Ce n'est que pendant le processus d'expansion de modèle qu'une chaîne de caractères dans un modèle d'URI est REQUISE (REQUIRED) pour être traitée comme une séquence de points de code Unicode.

La norme Unicode [UNIV6] définit diverses équivalences entre séquences de caractères à diverses fins. L'annexe #15 de la norme Unicode [UTR15] définit diverses formes de normalisation (Normalization Forms) pour ces équivalences. La forme de normalisation détermine comment encoder de manière cohérente des chaînes équivalentes. En théorie, toutes les implémentations de traitement d'URI, y compris les processeurs de modèles, devraient utiliser la même forme de normalisation pour générer une référence URI. En pratique, ce n'est pas le cas. Si une valeur a été fournie par le même serveur que la ressource, on peut alors supposer que la chaîne est déjà sous la forme attendue par ce serveur. Si une valeur est fournie par un utilisateur, par exemple via une boîte de dialogue de saisie de données, la chaîne DEVRAIT (SHOULD) être normalisée sous la forme de normalisation C (NFC : Canonical Decomposition, followed by Canonical Composition, décomposition canonique suivie de composition canonique) avant d'être utilisée dans les expansions par un processeur de modèle.

De même, lorsque des données non-ASCII représentant des chaînes lisibles sont encodées en pourcentage pour une utilisation dans une référence URI, un processeur de modèle DOIT (MUST) d'abord encoder la chaîne en UTF-8 [RFC3629], puis encoder en pourcentage tous les octets qui ne sont pas autorisés dans une référence URI.