ahn-ens-lyon / synopsx

Full XML corpus publishing system using BaseX XML database
Other
7 stars 11 forks source link

Le point sur les choix SynopsX de base #4

Closed mingarao closed 9 years ago

mingarao commented 10 years ago

Faire le point des choix de base faits pour le fonctionnement de SynopsX et les valider/modifier

Notamment (à compléter ?)

1 - nommage des bases, modules, etc.

actuellement : nom db = nom namespace module principal xquery = nom fichier teiCorpus maître ex : nom de la base de données = 'desanti' -> module principal xquery correspondant = desanti.xqm -> fichier TEI maître dans la bd = desanti.xml (= un teiCorpus qui organise les différentes ressources de la bases d'un point de vue documentaire en les déclarant par des xinclude = rendre les structures logiques explicites au niveau des ensembles de documents.)

2 - structure d'url prise en charge par défaut par SynopsX :

@ahn-ens-lyon/synopsx

emchateau commented 10 years ago

[avec @PhilPons]

1.

Tout le monde ne gère pas ses fichiers avec teiCorpus et xi. Cela pourrait constituer un frein à l'appropriation du module dans certaines situations. Ne pourrait-on pas être plus générique et prendre le chemin d'un répertoire ?

2.

OK pour partir avec le nom du projet à la racine

En revanche, je ne crois pas qu'il soit pertinent d'indiquer le format de sortie dans le chemin. Par exemple, une même URI pourrait fournir plusieurs représentations d'une même ressource = plus conforme à la logique de REST (laisser la négociation de contenu prendre en charge la question) Si on fait apparaître le format de sortie dans l'URI, cela ne doit être que pour contraindre spécifiquement le format de représentation.

Dans l'exemple donné, OAI désigne plutôt un protocole qu'un format, ici il désigne une ressource. Ressource à laquelle on peut passer des verbes et des arguments pour choisir le format de représentation (application/xml+tei, application/xml, …).

3.

Le choix de la logique descendante ou ascendante peut également être déterminé par des contraintes d'espace de nom. Il faudrait chercher à isoler le format de sortie défini par la fonction ressource (RESTxq) de l'écriture de la requête proprement-dite. La même requête pouvant être appelée par une ou plusieurs fonctions ressources (RESTxq) renvoyant différents formats selon les paramètres HTTP qui lui sont adressés. (à évaluer) Nous ne gèrerons pas que du texte en TEI, mais également des données bibliographiques, prosopographiques, etc. que l'on voudrait pouvoir représenter dans différents formats (autres que HTML).

mingarao commented 10 years ago

Merci pour ces retours ! Je suis convaincue par votre approche et je crois en effet que dans notre première mouture de SynopsX nous n'avons pas placé la gestion des différents output au bon endroit dans nos mécanismes... Jusqu'ici nous n'avons pas du tout exploité les possibilités de négociation de contenu de restxq (par exemple %rest:consumes("application/xml", "text/xml"), %rest:produces("application/atom+xml"), etc.) et nous gérons les demandes d'output par des variables ou des espaces de nom :( C'est à mon avis le plus gros point à reprendre et à régler dans l'immédiat pour pouvoir continuer à développer ensuite SynopsX. Je serai dessus aujourd'hui, mais je veux bien de l'aide :)

emchateau commented 10 years ago

On est en train de bosser avec Phil. Est-ce que tu disposerais d'une demi/heure aujourd'hui pour nous mettre en route sur un truc stp ? skype : emchateau

mingarao commented 10 years ago

Sur la question d'un document maître versus une organisation en dossiers/sous-dossiers :

mingarao commented 10 years ago

Sur la négociation de contenu, la gestion des reponses, etc., beaucoup de choses déjà ici : http://docs.basex.org/wiki/RESTXQ

mingarao commented 10 years ago

Donc une première mauvaise nouvelle, des annotations restxq différentes ne font pas deux fonctions différentes.

Les deux fonctions ci-dessous comme on le craignait provoquent une erreur "duplicate declaration of fonction", alors que dans la seconde on a ajouté une annotation rest:consumes et modifié l'annotation output:method.

Il faut donc adapter nos choix de structure...

declare %restxq:path("{$project}") %output:method("xhtml") %output:omit-xml-declaration("no") %output:doctype-public("xhtml") function synopsx_html:index($project) { let $params := map { "project" := $project, "dataType" := "home" }
return (:synopsx_html:html($params):) synopsx:function-lookup("html",map:get($params,"project"),"html")($params) };

declare %restxq:path("{$project}") %rest:consumes("application/xml", "text/xml") %output:method("text") %output:omit-xml-declaration("no") %output:doctype-public("xhtml") function synopsx_html:index($project) { let $params := map { "project" := $project, "dataType" := "home" }
return (:synopsx_html:html($params):) synopsx:function-lookup("html",map:get($params,"project"),"html")($params) };

Réponse : HTTP ERROR 400 Problem accessing /desanti. Reason: Stopped at /usr/local/basex-7.8/webapp/amalia/synopsx_html.xqm, 86/10: [XQST0034] Duplicate declaration of function 'synopsx_html:index'. Powered by Jetty://

emchateau commented 10 years ago

Pour le coup, cela n'est pas du tout cohérent avec la logique de REST. Il devrait y avoir un moyen de spécifier les différentes choses qu'est censée renvoyer une ressource selon les paramètres qui lui sont adressés.

Dans ce cas, la solution devrait-ête, à l'intérieur d'une fonction ressource, de créer une logique en fonction des paramètres de la requête HTTP qui lui sont adressés ? (je suppose avec HTTP leader) J'essayerai ce WE.

Sinon, il faudrait le signaler à l'équipe de BaseX car ce serait une très forte limitation de l'implémentation de RESTXQ.

jmague commented 10 years ago

Je pense que le fait qu'une fonction soit identifiée avec son nom et sa signature (nom, type et ordre des arguments) est profondément ancré dans xquery (comme dans plein d'autres langages) et que les annotations (notamment restxq) qu'on ajoute n'y changent rien. Et donc que les gens de basex ne peuvent rien a ca.

Ceci dit, ca ne me semble pas bien problèmatique. Dans une optique REST, pour désigner une ressource, ce qui est important, c'est l'URL plus que le nom de la fonction qui est derrière. Donc on peut sans que ca ne gene en quoi que ce soit avoir une seule fonction qui agit différemment selon le format de la ressource attendu (cf exemple 1 ci dessous). Ou alors, avec des fonctions différentes, avec des noms différents (cf exemple 2 ci dessous)

Exemple 1 : (A bien lire la doc, je pense que ce n'est pas possible d'avoir un variable associée a l'annotation rest:consume) declare %restxq:path("{$project}") %rest:consumes("{$format}") %output:method("text") %output:omit-xml-declaration("no") %output:doctype-public("xhtml") function synopsx_html:index($project,$format) { let $params := map { "project" := $project, "dataType" := "home" } if $format == "application/xml" return du xml if $format == "application/html" return du xml };

Exemple 2 : (copié-collé de l'exemple de Maud, ne renommant les fonctions) declare %restxq:path("{$project}") %output:method("xhtml") %output:omit-xml-declaration("no") %output:doctype-public("xhtml") function synopsx_html:index($project) { let $params := map { "project" := $project, "dataType" := "home" }

return (:synopsx_html:html($params):) synopsx:function-lookup("html",map:get($params,"project"),"html")($params) };

declare %restxq:path("{$project}") %rest:consumes("application/xml", "text/xml") %output:method("text") %output:omit-xml-declaration("no") %output:doctype-public("xhtml") function synopsx_xml:index($project) { let $params := map { "project" := $project, "dataType" := "home" }

return (:synopsx_html:html($params):) synopsx:function-lookup("html",map:get($params,"project"),"html")($params) };

jmague commented 10 years ago

Aucune des deux propositions avancées ci-dessus ne fonctionne : La première était d'avoir une variable associée a l'annotation %rest:consumes. Outre qu'il aurait plutot fallu l'associer a %rest:produces, c'est deux annotations fonctionnent comme des filtres a priori et ne peuvent avoir de variables associée.

La seconde était d'avoir des fonctions avec des nom différents, associées au meme chemin, mais avec des %rest:produces différents. Ce ne marche pas, car on ne peut pas avoir 2 fonctions associées au meme chemin (meme avec des %rest:consumes différents). Ce point est peut-etre a notifier aux concepteurs de basex.

Une troisieme solution fonctionnerait : il faut utiliser l'annotation %rest:header-param pour aller récupérer ce qui est annoncé dans le header de la requete :

declare %restxq:path("/test/ressource") %rest:header-param("Accept", "{$format}") function myproject:test ($format) {

{$format}

};

jmague commented 10 years ago

Pour pouvoir fonctionner par négo de contenu, il faut envoyer des requetes http dont on maitrise l'entete, notamment le champ Accept. Les navigateurs remplissent ce champ par défaut, sans tenir compte de l'attribut type des balises a. Si on veut pouvoir utiliser cet attribut pour indiquer dans le lien le format de la ressource pointée, il faut ajouter une couche de javascript qui construit le bon entete. cf http://stackoverflow.com/questions/20361216/how-can-i-set-the-accept-header-for-a-link-on-a-web-page

emchateau commented 10 years ago

Merci de ces précisions, Du coup, si nous voulons utiliser ce mécanisme il faudra écrire la logique dans la fonction avec les paramètres de l'entête.

Pour ce qui concerne les requêtes du client, je crois que la doc de BaseX renvoie à une extension de XPath que j'avais déjà repérée http://expath.org/modules/http-client/

Je pense qu'il n'y a rien besoin de préciser de la part du client pour servir du HTML. Il faudra que cela soit le comportement par défaut pour une requête GET envoyée par un navigateur. Là où il pourrait être intéressant de préciser les choses, c'est si nous voulons construire un truc qui ressemble plus à une API pour interagir avec les ressources.

En faisant les tests, il faudra aussi vérifier s'il ne faut pas aussi activer une option sur le serveur jetty pour la négociation de contenu car c'est le cas avec Apache http.

mingarao commented 10 years ago

Après le passage par Constance, nouvelle piste d'architecture : mettre nos modules dans repo/ et non tout dans restxq/. Cela engendre une profonde réorganisation du code. Avantage : un même module avec un même espace de nom peut être fractionné en plusieurs fichiers. Inconvénient : deux répertoires à télécharger pour installer SynopsX (webapp et repo) A décider...