Raccourcis:

Pour poster des messages sur le forum, merci de vous connecter ou de créer un compte utilisateur.

Api et respect des fondamentaux de l'architecture REST


Auteur Message
le: 09. 03. 2011 [10:57]
bmoraillon
bmoraillon
Auteur du fil
Inscrit depuis: 12.10.2010
Interventions: 3
Bonjour,
Ce projet est formidable.
Pouvez vous m'indiquez les raisons techniques qui vous ont poussés
à utiliser un langage spécifique de commande :
cmd=getsubtheme&param[theme]=11&param[subtheme]=43

en lieu et place d'une URI qui serait plus conforme aux fondamentaux de l'architecture REST:

/subtheme/43 par exemple pour accéder au sous-thème dont l'identifiant est 43.

De même, pouvez vous m'indiquer pour quelles raisons une ressource non trouvé via l'API produit tout de même une réponse XML avec un status code HTTP 200 alors que l'architecture REST prévoit le renvoi d'un code HTTP 404 ?

GET HTTP method (Retrieve)

* Success = 200
* Client error = 4xx
o Resource not found = 404
o Forbidden operation = 403
* Server error = 5xx
o Default = 500
o Overload = 503


Enfin, le choix du format pour les réponses (JSON ou XML) devrait être fonction du header http de la request :
Accept application/json
et non d'un paramétrage spécifique de l'URI de la ressource.

Merci par avance et bonne continuation




[Cette intervention à été corrigée 3 fois, en dernier le 09.03.2011 à 11:59.]
le: 09. 03. 2011 [14:45]
Sebastien Tanguy
Sebastien Tanguy
Inscrit depuis: 07.09.2010
Interventions: 27
[à noter que je parle juste en mon nom]
bmoraillon a écrit :

Bonjour,
Ce projet est formidable.
Pouvez vous m'indiquez les raisons techniques qui vous ont poussés
à utiliser un langage spécifique de commande :
cmd=getsubtheme&param[theme]=11&param[subtheme]=43

en lieu et place d'une URI qui serait plus conforme aux fondamentaux de l'architecture REST:


Attention, attention, à l'origine l'API n'a jamais (il me semble) été qualifiée comme étant du REST et la convention d'appel vient plutôt d'usages plus généralistes (je dirais php, par hasard).

Ce n'est que récemment que le mot REST a été collé sur l'API avec la nouvelle version du site (cf une autre discussion sur le forum où je grognais justement sur cette appellation).
[Edit: D'ailleurs, REST a disparu, c'est bien API qui est le terme utilisé]


De même, pouvez vous m'indiquer pour quelles raisons une ressource non trouvé via l'API produit tout de même une réponse XML avec un status code HTTP 200 alors que l'architecture REST prévoit le renvoi d'un code HTTP 404 ?


J'avais cru voir certaines littératures qui indiquaient, pour ce genre de pratiques, que certains environnements ne sont pas fichu de pouvoir retrouver le code HTTP (je soupçonnerais bien flash, mais certains disent que je suis mauvaise langue et je connais peu ce milieu) donc ce qui rend nécessaire ce genre de choses affreuses.

Après, on pourrait aussi se demander si faire du "vrai" REST ici est vraiment utile, vu qu'il ne s'agit que d'une API en consultation (donc pas de PUT/POST/DELETE) et la moitié du temps même pas de vraie requête sur une ressource unique.
(enfin, sans casser complètement tout l'existant, sachant qu'il y a de l'historique à se taper pour les gens derrière l'API -- mes condoléances)

[Cette intervention à été corrigée 2 fois, en dernier le 09.03.2011 à 15:10.]
le: 09. 03. 2011 [21:30]
bmoraillon
bmoraillon
Auteur du fil
Inscrit depuis: 12.10.2010
Interventions: 3
Le protocole HTTP est un protocole applicatif, pas un protocole de transport. Cela signifie que les status code HTTP doivent s'appliquer aux services applicatifs mis à disposition sur le web.

Une lecture précise de la spécification HTTP montre que les status code >= 400 doivent être utilisés avec un corps de message contenant une traduction intelligible pour l'être humain de l'erreur qui est survenu sur le service applicatif.

Le fait de retourner systématiquement un status code en 2xx
va à l'encontre du paradigme demande / réponse et pose également des problèmes au niveau du cache des clients (rfc2616).






[Cette intervention à été corrigée 1 fois, en dernier le 09.03.2011 à 21:33.]
le: 09. 03. 2011 [23:45]
Sebastien Tanguy
Sebastien Tanguy
Inscrit depuis: 07.09.2010
Interventions: 27
Je suppose que les choix de la plateforme API de Rennes Métropole ont été faits en considération de contraintes particulières d'implémentation (via Typo3) ou d'utilisation (Flash et les plugins NSAPI sont l'exemple de base).

Après, cette même plateforme est elle-même opensource, donc je suis sûr que les gens de In Cité (qui sont derrière) seront ravi de recevoir les patchs adéquats icon_smile.gif.

(pour ce qui est des questions de cache, d'un côté les entêtes renvoyés ne contiennent pas les informations nécessaires et l'utilisation de query string aura tendance à invalider les cacher, et de l'autre l'API telle qu'elle est définie ne se prête pas forcément très bien à la mise en place d'un cache client).
le: 14. 03. 2011 [12:52]
Lawouach
Lawouach
Inscrit depuis: 24.11.2010
Interventions: 54
bmoraillon a écrit :

De même, pouvez vous m'indiquer pour quelles raisons une ressource non trouvé via l'API produit tout de même une réponse XML avec un status code HTTP 200 alors que l'architecture REST prévoit le renvoi d'un code HTTP 404 ?


Techniquement le modèle proposé par REST ne parle pas de code de retour et HTTP n'est qu'un moyen de faire du REST, pas une finalité.

Mais je suis d'accord que l'API actuelle ne joue pas correctement avec ce qui se défini depuis des années dans les standards du web.

bmoraillon a écrit :

Enfin, le choix du format pour les réponses (JSON ou XML) devrait être fonction du header http de la request :
Accept application/json
et non d'un paramétrage spécifique de l'URI de la ressource.


Je suis d'accord bien que la négociation de contenue ne soit pas toujours très bien supportée par les serveurs et intermédiaires.

Clairement l'API n'est pas très agréable ni "standard" quand on considère les services webs actuels. Il me semble que l'implémentation PHP et Typo remontent beaucoup trop dans l'API finale.

Elle mériterait une réflexion profonde. Ceci étant, à mon sens, la question va au delà de l'architecture actuelle et remonte à ce que Rennes et Keolis souhaitent proposer comme ressources.

Gageons qu'il était difficile avant de voir fleurir les applications de déterminer les besoins finaux. Maintenant qu'il existe un bon panel d'apps, il serait pertinent de regarder ce qui est le plus souvent utilisé, demander aux developpeurs d'applications si ils doivent passer par un modèle interne intermédiaire ou si ils peuvent construire leur app sur l'API existante. J'ai du créer un modèle intermédiaire pour ma part.

J'espère qu'on aura à terme une API plus pertinente et mieux conçue effectivement.

Typiquement quelque chose comme ceci:

/transit/bus/stop/republique/routes
/transit/bus/route/4/stop/republique/timetable
/transit/bus/stop/closest?latlon=

Il faudrait donc définir quelles sont les ressources internes que Keolis et Rennes veulent exposer pour en déterminer la meilleure API.

Etudier le protocole AtomPub est toujours intéressant icon_smile.gif



[Cette intervention à été corrigée 3 fois, en dernier le 14.03.2011 à 18:02.]

--
- Sylvain
http://urbanility.com
le: 15. 03. 2011 [20:04]
MyGoddess
MyGoddess
Inscrit depuis: 03.09.2010
Interventions: 2
Bonjour,

En tant que concepteur de l'API, je comprends très bien vos interrogations.

Les motivations de nos choix étaient entre autres : la simplicité de mise en œuvre, la simplicité d'interrogation, et l'intégration à la plateforme sous-jacente tout en restant extensible.

Concernant l'architecture, nous avons explicitement choisi de ne pas nous conformer à une norme existant précise. En effet, elles imposent souvent des contraintes qui allaient au-delà de notre volonté de simplicité. Vous parlez d'architecture REST. Cette architecture est faite pour de la requête mais aussi de la mise à jour. Notre but étant de fournir une API d'interrogation uniquement, REST demandait trop de traitements supplémentaires. Les autres normes étant aussi émergeantes.

Concernant les codes d'erreur HTTP, toute comparaison à REST est à écarter. Il est vrai qu'en cas d’« erreur » nous ne transmettons pas d’état HTTP. Les best practices nous signalent d'y faire attention. Les raisons que l'API fournisse tout le temps en code 200, c'est d'une part que dans tous les cas la requête abouti. En effet, une réponse est renvoyée. Un autre résultat serait reçu si l'API était introuvable (extension TYPO3 non installée...). Et d'autre part, que certaines méthodes d'interrogation d'API Web permettent au développeur d'ignorer ces codes, ou ne permettent pas de les récupérer. Dans le souci de simplicité de conception, et le corps de la réponse devant être toujours traité, même en cas d'erreur, il n'a pas semblé obligatoire de définir une correspondance avec un état HTTP. Il n'y a donc rien eu de prévue pour permettre de personnaliser celui-ci.

Concernant la négociation du type de contenu, là encore il aurait fallu définir une priorité des types de contenus. Dans un premier temps, nous n'avions défini qu'une fourniture en XML des données. Certains développeurs nous avaient demandé si l'on ne pouvait pas ajouter une sortie JSON. Nous l'avons fait, l'estimant pertinente. Nous avons donc choisi de rajouter un paramètre de sélection du type de sortie, ce qui est assez courant (cf. Apache SOLR, Google Search Appliance, ...). La négociation de contenu requière aussi que l'API utilisée pour exécuter la requête HTTP permette de définir les en-têtes, ce qui n'est parfois pas autorisé pour des raisons de sécurité ou de simplicité d'implémentation. Dans ce cas-là, si nous avions défini XML par défaut et que le développeur souhaitait du JSON et qu'il ne peut pas définir les en-têtes, un blocage survient.

Concernant les problèmes de cache, ils ne peuvent survenir qu’avec les navigateurs ou les proxys. L'utilisation de paramètres d'url empêche la mise en cache. Il est aussi possible d'interroger en POST.

Je rajouterais que vous êtes bien écoutés, et que la manière dont est réalisé l'API permet une certaine flexibilité et extensibilité. Je vois assez bien, entre autres, plusieurs manières de rajouter les trois points demandés : format des URL, retours de codes d'erreur, négociation de contenu, en-tête explicitant l’exclusion du cache.

Je pense que les but rappelés au début de ce message sont tous atteint : l'écriture du noyau a été rapide, l'écriture des commandes est assez simple, l'écriture d'une requête d'interrogation est comme un texte à trous, l'intégration à TYPO3 bonne et l'extensibilité correct, même si pouvant être améliorée.

Merci pour vos commentaires
Pierrick Caillon, In Cité Solution

NB: Ces éléments de réponse n'engagent que moi-même et ne proviennent pas d'une concertation à l'écriture de ce message. Je laisse donc la possibilité à mes collègues de valider ou d'invalider mes propos.
le: 17. 03. 2011 [09:35]
Lawouach
Lawouach
Inscrit depuis: 24.11.2010
Interventions: 54
Bonjour,

Il est probablement plus simple et rapide en effet de créer un RPC adhoc que de définir une API REST puisque cette dernière requiert d'avoir déjà en amont de relativement bien percevoir les usages finaux des données servies.

J'entends les limitations et contraintes que vous avez souhaité prendre en compte (codes d'erreur, impossibilité de traiter les headers HTTP, etc.) mais je pense que vous avez été trop conservateur.

En effet, vous proposez un service web (qu'il soit RPC ne change rien) et il me paraît évident que ce service web est consommé par des développeurs qui ont accès à des librairies HTTP qui ne les brident pas. Citez moi un cas où un développeur n'a pas directement accès aux méta-données HTTP. Le seul problème que je peux voir serait les intermédiaires comme les proxys dont nous n'avons pas le contrôle.

Quoiqu'il en soit, même si je comprends vos choix initiaux au vue des contraintes que vous pouviez avoir ou imaginer, j'espère qu'il y aura une réflexion se basant sur les applications qui ont été développées pour mieux comprendre les usages et les difficultés rencontrées avec le modèle actuel.

D'un point de vue personnel, le modèle RPC n'abstrait pas correctement mais en général fini par ressembler un plat de spaghetti de fonctions sans cohérence au niveau globale. REST évidemment n'est pas magique et peut terminer dans une API inutilisable mais force plus, je pense, à réfléchir à la "vue" que l'on veut donner à ses données.

D'un autre côté, on touche là, à une question de l'opendata. Les fournisseurs doivent-ils prendre partie dans la modélisation de leurs données ou les proposer de manière brute ? C'est un débat que Rennes et Keolis auront peut-être icon_smile.gif



--
- Sylvain
http://urbanility.com
le: 17. 03. 2011 [10:39]
Sebastien Tanguy
Sebastien Tanguy
Inscrit depuis: 07.09.2010
Interventions: 27
Lawouach a écrit :

Bonjour,

Il est probablement plus simple et rapide en effet de créer un RPC adhoc que de définir une API REST puisque cette dernière requiert d'avoir déjà en amont de relativement bien percevoir les usages finaux des données servies.


Et bien, il me semble que c'est le cas ici, non? L'API a été conçue dans un but d'effectuer des recherches (par nom, localisation et autres critères), pas de gérer des ressources, et dans ce cadre, du "RPC" (spécifique ou non) me semble plus pertinent aussi que du REST (cf Google, qui fait pareil).

À la limite, vu certains usages pour les données VàR, sans information sur la fréquence de mise à jour des données, peut-être aurait-il même été plus pertinent de fournir des données brutes, justement (combien ici ont écrit des scripts/programmes pour tout récupérer, travailler en local ou remodéliser les données?)


En effet, vous proposez un service web (qu'il soit RPC ne change rien) et il me paraît évident que ce service web est consommé par des développeurs qui ont accès à des librairies HTTP qui ne les brident pas. Citez moi un cas où un développeur n'a pas directement accès aux méta-données HTTP.


Flash? Et en général les plugins passant par NSAPI ? (même si, récemment, le problème s'estompe, cela reste un point gênant pour certains, je suppose)


Le seul problème que je peux voir serait les intermédiaires comme les proxys dont nous n'avons pas le contrôle.


Parlons en justement: Dont nous n'avons pas le contrôle mais que nous subissons parfois quand même. Plus d'un opérateur télécom (ou entité un peu grosse) ne se gêne pas pour placer un proxy (transparent ou non) dont la compréhension du HTTP peut être variable (incorrecte ou simplement sécuritaire).

Donc un solution "obsolète" et conservatrice est parfois nécessaire pour couvrir un maximum de bases.


D'un autre côté, on touche là, à une question de l'opendata. Les fournisseurs doivent-ils prendre partie dans la modélisation de leurs données ou les proposer de manière brute ? C'est un débat que Rennes et Keolis auront peut-être icon_smile.gif


On a le bon double-exemple sous notre nez: l'API d'un côté (avec ses joies, ses bonheurs, ses bugs et ses limitations) et les données (brutes) GTFS de l'autre. N'avoir qu'une solution à base d'API pour les données bus (en particulier en REST) n'aurait certainement pas ravi certains. D'autant qu'on a vu plus d'une personne créer des services à côté et les offrir (utilisés ou non).

D'un côté ou de l'autre, c'est un effort de la part du fournisseur et un coût (récurrent). Hors standards existants (et pas juste sur la couche RPC, je parle de la manière d'accéder aux données à proprement parler) un développement reste nécessaire. Pour un utilisateur final (non développeur), la différence n'existe pas (et en fait que "lui" ne puisse pas utiliser ces données reste un problème à régler).

Pour ma part, je ne pense pas que la question API vs données brutes se pose sur une question de modélisation (qui sera toujours présente dans un sens, il ne faut pas se leurrer) ou non, mais simplement sur une question plutôt de validité des données: certaines données ne sont pas amenées à changer à court terme, certaines évoluent en permanence (pseudo-temps réel ou non).

Et si un développeur sait accéder aux méta-données HTTP, je pense qu'il arrivera bien à lire un fichier CSV (ou XML).

Après, je suis d'accord pour améliorer l'API, que ce soit du haut niveau (genre, si quelqu'un arrive à proposer une vraie solution pour traiter la gestion des horaires) ou du bas (bouhouh, je veux mon jsonp!), mais dans ce cas, ce serait bien de proposer du concret (et pas pour les bus, quoi) et d'avancer petit à petit avec ce qui existe plutôt que de tout jeter d'un seul bloc.
le: 17. 03. 2011 [11:32]
ybonnel
ybonnel
Inscrit depuis: 11.01.2011
Interventions: 19
Bon allez, je vais rajouter mon grain de sel icon_smile.gif

Pour ce qui est du REST vs l'existant, je trouve ça superflu, d'un point de vu opérationnel j'ai du mal à voir la valeur ajoutée hormis pour l'esthétique.

Je pense que la priorité pour permettre l'utilisation par de nouveau développeur serait plutôt une documentation plus complète (type + explication de tous les champs...), et une documentation technique associée (xsd, dtd, autre?).

++
Yan.
le: 17. 03. 2011 [12:03]
Lawouach
Lawouach
Inscrit depuis: 24.11.2010
Interventions: 54
Sebastien Tanguy a écrit :

Et bien, il me semble que c'est le cas ici, non? L'API a été conçue dans un but d'effectuer des recherches (par nom, localisation et autres critères), pas de gérer des ressources, et dans ce cadre, du "RPC" (spécifique ou non) me semble plus pertinent aussi que du REST (cf Google, qui fait pareil).


Je ne voies pas en quoi une API orientée ressource ne pourrait pas réaliser les mêmes opérations. C'est orthogonal. La notion de ressource, au sens REST du moins, est le nommage de quelque chose de concret comme un fichier, d'un modèle, ou d'un concept. En cela on peut très bien considérer une recherche comme une ressource. Certes du RPC est plus évident à mettre en place et je peux comprendre son utilisation dans la première phase mais je ne suis pas certain qu'un RPC adhoc vive mieux les années (ahem SOAP, XML-RPC... on en revient).

je suis curieux de voir où Google utilise si intensivement du RPC ceci dit icon_smile.gif


Sebastien Tanguy a écrit :

À la limite, vu certains usages pour les données VàR, sans information sur la fréquence de mise à jour des données, peut-être aurait-il même été plus pertinent de fournir des données brutes, justement (combien ici ont écrit des scripts/programmes pour tout récupérer, travailler en local ou remodéliser les données?)


Effectivement.

Sebastien Tanguy a écrit :

Flash? Et en général les plugins passant par NSAPI ? (même si, récemment, le problème s'estompe, cela reste un point gênant pour certains, je suppose)


Mais cela est-ce effectivement la cible si l'API pousse à créer son modèle intermédiaire. Mais soit, la négociation de contenue n'est pas simple.


Sebastien Tanguy a écrit :

Parlons en justement: Dont nous n'avons pas le contrôle mais que nous subissons parfois quand même. Plus d'un opérateur télécom (ou entité un peu grosse) ne se gêne pas pour placer un proxy (transparent ou non) dont la compréhension du HTTP peut être variable (incorrecte ou simplement sécuritaire).

Donc un solution "obsolète" et conservatrice est parfois nécessaire pour couvrir un maximum de bases.



Allez dire cela à Twitter, Facebook ou Google qui utilisent massivement des API orientées ressources.

Sebastien Tanguy a écrit :

On a le bon double-exemple sous notre nez: l'API d'un côté (avec ses joies, ses bonheurs, ses bugs et ses limitations) et les données (brutes) GTFS de l'autre. N'avoir qu'une solution à base d'API pour les données bus (en particulier en REST) n'aurait certainement pas ravi certains. D'autant qu'on a vu plus d'une personne créer des services à côté et les offrir (utilisés ou non).

D'un côté ou de l'autre, c'est un effort de la part du fournisseur et un coût (récurrent). Hors standards existants (et pas juste sur la couche RPC, je parle de la manière d'accéder aux données à proprement parler) un développement reste nécessaire. Pour un utilisateur final (non développeur), la différence n'existe pas (et en fait que "lui" ne puisse pas utiliser ces données reste un problème à régler).



C'est bien la question que je posais effectivement.

Sebastien Tanguy a écrit :

Après, je suis d'accord pour améliorer l'API, que ce soit du haut niveau (genre, si quelqu'un arrive à proposer une vraie solution pour traiter la gestion des horaires) ou du bas (bouhouh, je veux mon jsonp!), mais dans ce cas, ce serait bien de proposer du concret (et pas pour les bus, quoi) et d'avancer petit à petit avec ce qui existe plutôt que de tout jeter d'un seul bloc.


D'où l'idée de réflexion en se basant sur la manière dont les app ont été conçues.

--
- Sylvain
http://urbanility.com