/
complete_protocol.txt
executable file
·158 lines (104 loc) · 8.32 KB
/
complete_protocol.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
=============================================
= Protocole pour le filtre autocomplete =
=============================================
Auteur: Antoine Yersin
Date: 31/5/2010
Ce document présente les principaux points clés du protocole à mettre en place pour le filtre autocomplete.
Messages du client
------------------
Ce protocole défini les messages échangés depuis le client vers le serveur.
Le client doit envoyer les informations suivantes :
a) URI de la ressource
b) requête pour la complétion
c) (optionnel) limite pour le nombre de résultats
Ces informations sont discutées ci-dessous:
a) URI de la ressource
Le but est d'identifier quelle ressource interroger pour obtenir une liste de suggestions. Voici les options disponibles :
- accès par service. Un service identifié par une URL est invoqué avec des paramètres. Nous nous intéressons ici à l'identification de la ressource.
- un identifiant simple (texte). Un mapping id <-> ressource/requête est codé en dur dans le serveur.
ex : http://www.madeinlocal.com/autocomplete?resource="Artists"&...
- URI de la ressource ajoutée à l'URL du service.
ex : http://www.madeinlocal.com/autocomplete/Artists?...
- URI d'une ressource (XPath) passé en paramètre
ex : http://www.madeinlocal.com/autocomplete?path="/data/Events/Event/Artists/Artist/artist_name"&...
- accès par ressource
- requête de type REST
ex : http://www.madeinlocal.com/data/artists.json?match="Micha"&...
Dans le cas d'un premier développement, le plus simple est d'avoir des requêtes pré-enregistrées dans le serveur. Ces requêtes sont accédées comme des ressources et prennent les paramètres passés par le massage GET. Le schéma proposé est celui de le seconde proposition (http://www.madeinlocal.com/autocomplete/Artists?...). Il permet de rajouter facilement un nouveau champ auto-complétable en enregistrant une nouvelle requête.
b) requête pour la complétion
Le but est d'avoir un critère pour extraire les résultats de la complétion. Voici les options disponibles :
- un string interprété comme une requête "begin with"
- un string interprété comme une requête "contains"
- un string "REGEXP-like". Par exemple "Mic" pour contains et "^Mic" pour begin with
L'autre aspect concerne la canonisation de ces données (majuscules/minuscules, accents, espaces...). Le but est de retourner un maximum de résultats pertinents par rapport à l'entrée de l'utilisateur. Les solutions suivantes peuvent être explorées.
- Ignore case. (tout convertir en minuscule)
- Supprimer les accents éèê -> e
- Normaliser les espaces. Pas de leading/trailing spaces, les espaces multiples et les caractères \n\t.. sont convertis en espaces simples.
- Supprimer la ponctuation. (attention dans les cas où la ponctuation peut être pertinente)
Une question demeure quant à savoir si cette canonisation se fait au niveau du client ou du serveur. Une réponse possible serait les deux. Au niveau du client afin d'assurer une syntaxe correcte de l'URL et au niveau du serveur pour avoir un sanitize des éléments de la requête (sécurité, évitement d'attaques par injection)
c) limite
Une limite pour n'obtenir que n résultats au maximum
Messages du serveur
-------------------
Le serveur doit renvoyer les résultats avec les informations suivantes :
d) une liste de résultats. Chaque résultat contient les informations suivantes :
d1) une valeur (string) qui est celle entrée dans le champ comme résultat de la complétion
d2) (optionnel) un bout de HTML pour de l'affichage riche
d3) (non-applicable ici) des méta-informations (liens wikipedia, segmentation)
e) une valeur booléenne hasMore qui indique si il existe plus de résultats que ceux envoyé pour cette requête (pertinent en cas de c) limite)
Ces informations sont discutées ci-dessous:
d) Structure d'un résultat
d1) value
La valeur que prendra le champ lorsque cette suggestion d'auto-complétion est sélectionnée.
d2) display
Un bout de code HTML qui peut être inséré dans une balise <LI> afin d'obtenir un affichage riche. Dans le cas où cette valeur n'est pas fournie, une valeur par défaut basée sur le champ d1-valeur est construite.
d3) meta-inf
Un objet JSON fournissant des informations supplémentaires. Celles-ci pourrait par exemple fournir un moyen de segmenter une liste de résultats, donner accès à des informations supplémentaires comme un lien vers un page wikipédia, etc. Ce point ne sera pas exploré plus avant car il rentre en compétition avec l'avantage visé par la fonctionnalité "pre-fill".
proposition de syntaxe des messages
-----------------------------------
L'envoi d'une requête au serveur se fait via un message HTTP GET. Deux possibilités s'offrent pour encoder cette requête:
- GET http://url/to/autocomplete/service?resource="resource_URI"&query="fla"&limit=x
- GET http://url/to/autocomplete/service/resource_URI?query="fla"&limit=x
Il est plus pertinent, dans le cas du choix de la solution proposée au point a), d'encoder l'URI de la ressource dans l'URL de la requête. Cela permet d'accéder à des requêtes pré-enregistrées comme à des ressources web standards.
Le serveur peut renvoyer les résultats d'une requête dans les trois formats suivants :
- texte plein
- JSON
- XML
Le format texte plein est inadapté, car il faudrait créer un langage ad-hoc pour encoder le paramètre "hasMore" et l'encodage du HTML de présentation (d2) serait compliqué. XML pourrait faire l'affaire, mais nécessite un parsage plus compliqué dans le client et contient un overhead important.
La solution recommandée est donc JSON, selon la structure suivante (corps de la réponse pour une query="Mic"):
{results: [{value: "Mica", display: "<span>Mica</span><img src=\"...\"/>"}, {value: "Michael Jackson, display: "..."}, {value: "Mickey 3D, display: "..."}, ...], hasMore: true/false}
Traitement des requêtes au niveau serveur
-----------------------------------------
Ici sont discutés deux éléments concernant le traitement d'une requête par le serveur.
Sélection d'un sous-ensemble de résultats
.........................................
Ce cas intervient quand le nombre de résultats d'une requêtes dépasse la le paramètre "limit". Il faut à ce moment sélectionner un sous-ensemble de résultats à envoyer au client. Voici une liste des stratégies de sélection :
- Sélectionner les n premiers résultats
- Aléatoire
- Alphabétique (ou autre critère statique)
- Traitement statistique ("popularité", nombre de sélection)
- En fonctions de l'historique (les + récemment sélectionnés)
- En fonction du profil de l'utilisateur (goûts). Possibilité d'inférer des données.
- En fonction du contexte de la vitrine (connu du serveur. par ex. tags de l'événement). Possibilité d'inférer des données.
- En fonction du contexte de l'édition du template en cours. Possibilité d'inférer des données. Nécessite du développement client-side probablement lourd.
Pour une première approche, seules les trois premières approches nous semblent envisageables afin de limiter les coûts de développements.
Tri/ordonnancement de la liste des résultats
............................................
Cet ordre sera repris pour l'affichage de la liste des suggestions. La stratégie peut être la même que pour la sélection d'un sous-ensemble de résultats.
Autentification et sécurité
...........................
Le serveur doit aussi gérer les aspects sécuritaires du service d'auto-complétion. Ce service ne doit pas permettre de récupérer des données qui ne sont pas destinées à être largement publiée. De plus, un contrôle d'accès est nécessaire afin d'éviter des attaques DoS par "flood". Un système de session tel que probablement déjà en place sur madeinlocal.com semble suffisant à ce propos.
Résumé des propositions
-----------------------
Message envoyé par le client :
GET http://www.madeinlocal.com/autocomplete/Artists?query="Mic"&limit=200
Réponse du serveur :
mime-type: text/json
{results: [
{value: "Mica", display: "<span>Mica</span><img src=\"...\"/>"},
{value: "Michael Jackson, display: "<span>Mica</span><img src=\"...\"/>"},
{value: "Mickey 3D, display: "<span>Mica</span><img src=\"...\"/>"},
...
],
hasMore: true/false}
Note : le champ display : 'inner html' est facultatif pour une première implémentation