La quatrième version d'OData, le standard soutenu par Microsoft pour l'interrogation de données à l'appui de conventions REST, a été accepté par le comité OASIS. La période de consultation publique va courir jusqu'au 2 juin et Microsoft compte voir l'adoption du standard par l'OASIS effective dans le courant de l'année. Parmi les autres sponsors de ce standard se trouvent SAP, IBM, Progress Software, Northeastern University, et Citrix. SAP propose d'ores et déjà une librairie OData open source pour Java. Côté JavaScript, JayData supporte à la fois une version open source et une version commerciale.
La spécification complète peut être trouvée sur la page documentation de OData.org. Toutefois, cette page ne présente pas les différences entre versions. Nous nous tournons donc vers le résumé de Michael Pizzo :
1) Changements au niveau du modèle de données. Quelques changements ont été apportés sur la façon dont est exprimé le modèle de données dans le CSDL, notamment :
a) Changement significatif et simplification de l'expression des relations. Les définitions des relations sont maintenant exprimées comme faisant partie des propriétés de navigation, plutôt que d'avoir à spécifier séparément une association sous forme d'"association" et "association set". Entre autres, cela permet le support des relations unidirectionnelles et une vraie notion de "contenance".
b) La notion d'"entité nommée" à la racine de votre conteneur d'entités, les "Top-Level Named Entities", qui vous permettent d'exposer une entité singleton au plus haut niveau de votre conteneur.
c) Les fonctions et actions sont maintenant définies dans le schéma (au même titre que les entités et types complexes) et PEUVENT être exposées depuis votre conteneur d'entités grâce à des instructions d'import (Function/Action imports).
d) Les "Service Documents" exposés par le service OData peuvent à présent inclure des Top-Level Named Entities, ainsi que des imports de fonctions sans paramètre.
e) La prise en charge du versioning des métadonnées a été ajoutée, via les etags.
f) Les modèles de données distribués ont été étoffés en affinant la définition de l'élément <references>, pour faire en sorte que les schémas puissent référencer d'autres schémas et s'assurer que les instances puissent retrouver leur métadonnées en JSON et ATOM.
g) Nous avons commencé à définir comment un service pourrait exposer des métadonnées en tant que service. Ce point a été ajouté assez récemment et nous apprécierons fort avoir vos retours sur le modèle et tout ce qu'il y a autour.
h) Nous avons relâché certaines contraintes sur les propriétés des types complexes. Les propriétés faisant office de clé pour une entité peuvent maintenant se trouver sur un type complexe à l'intérieur du type, de même pour les propriétés de navigation et les contraintes référentielles. Nous avons également défini des sémantiques d'héritage pour les types complexes.
i) Nous permettons que les types d'entités abstraites soient définis sans clé. Le premier type dérivé non abstrait doit alors spécifier la clé si elle n'a pas été spécifiée.
j) Quelques changements ont été effectués autour des annotations. En particulier, nous avons fusionné TypeAnnotations et ValueAnnotations, ajouté des valeurs par défaut et l'attribut "AppliesTo". Nous avons commencé à définir un noyau de vocabulaire pour capturer certains aspects comportementaux du modèle (comme des propriétés générées par le serveur pour l'identité, des champs calculés, etc.)
2) Changements au niveau des types de données.. Nous avons ajusté l'ensemble des types primitifs (en particulier l'ensemble des types liés aux dates et heures) :
a) Nous avons supprimé Edm.Float (synonyme d'Edm.Single) et Edm.DateTime (utiliser Edm.DateTimeOffset) et rendu obsolète Edm.Time en faveur d'Edm.Duration et Edm.TimeOfDay.
b) Nous avons ajouté les fonctions canoniques appropriées pour les nouveaux types de données, ainsi que les fonctions now(), mindatetime(), maxdatetime().
c) La syntaxe littérale et les formats de sérialisation ont été définis pour les énumérations.
d) Nous avons introduit les abstractions "Edm.EntityType", "Edm.ComplexType", "Edm.PrimitiveType" et des collections pour chacune. Celles-ci peuvent être utilisées dans un modèle de données là où le type de l'entité, du type complexe ou du type primitif n'est pas connu. Le type réel est spécifié dans le contenu du message.
e) Le concept de référence à une entité a été introduit. Dans de nombreuses circonstances, il peut être retourné à la place d'une entité complète.
f) Nous avons ajouté le concept de "TypeDefinition" pour le nommage des primitives et un ensemble de facettes utilisables sur les propriétés.
3) Changements au niveau des URLs.
a) Nous avons modifié la façon dont sont exprimés les "expand". $expand prend maintenant des options spécifiques, dont $filter (pour obtenir un "expand" filtré), $orderby, etc. et peut prendre également des $expand ou des $select pour des projections imbriquées, plutôt que d'avoir à exprimer ceci sous la forme d'un chemin fait de propriétés de navigation partant du $expand/$select de plus haut niveau. Et pour les "expand" récursifs, nous avons aussi ajouté "$levels".
b) Nous avons ajouté un système d'options pour les requêtes de type $search pour faire des recherches plein texte sur l'ensemble d'une ressource.
c) $count remplace $inlinecount et peut être appliqué aux collections ou aux propriétés de navigation de la forme "to-many" pour filtrer. Il peut être utilisé pour retourner le compte d'entités liées plutôt que les entités elles-mêmes.
4) Changements de sémantique. Nous avons affiné certaines sémantiques autour de la façon dont sont traitées les requêtes. Plus précisément :
a) Nous avons ajouté une section décrivant différents niveaux de conformité au standard. C'est un autre sujet sur lequel nous aimerions avoir vos retours. Nous le savons tous, la spécification est volumineuse et nous voulons nous assurer que ceux qui l'implémentent sachent qu'il n'est pas nécessaire de l'implémenter dans sa totalité pour être en conformité.
b) Nous avons étoffé tout ce qui tourne autour du comportement de $batch : ceci comprend la prise en charge des retours asynchrones et le comportement attendu en cas d'erreur ("continue" ou "fail").
c) Nous encourageons fortement l'utilisation de PATCH plutôt que PUT pour la mise à jour d'entités et types complexes. Nous avons ici clarifié le comportement de PATCH pour les types complexes : PATCH n'est censé mettre à jour que les propriétés spécifiées.
d) Nous avons mis en conformité l'entête Prefer avec le tout dernier draft de l'IETF et avons ajouté un certain nombre de préférences que le client peut utiliser pour suggérer au service un comportement souhaité.
e) Nous supportons UPSERT, qui correspond à un PUT ou PATCH sur l'URL d'une ressource non existante.
5) Extension des services. De nouvelles options sont supportées :
a) Exécution asynchrone, définie via un entête "return-async" dans la requête, conformément aux dernières réflexions de l'IETF.
b) Le support du Tracking des changements (par delta) fait maintenant partie de la spécification. Il est spécifié comme retournant uniquement les différences par rapport à un résultat récupéré précédemment et des sémantiques sont définies pour tracer les changements apportés à un ensemble d'entités liées. Pour chaque format, tous les détails pour représenter les entités supprimées et les liens ajoutés ou supprimés ont été documentés.
6) Formats
a) L'ancien format "JSON Verbose" a été rendu obsolète, en faveur du nouveau "JSON", plus propre.
b) Il n'est plus obligatoire que les services supportent ATOM. Un service DOIT implémenter soit ATOM, soit JSON. Nous suggérons d'utiliser JSON et son support fait partie des critères de conformité les plus forts.
c) Le format ATOM inclut à présent une URL pour les métadonnées de la réponse et peut inclure une URL pour les métadonnées des propriétés de navigation si les informations de types ne peuvent pas être dérivées de l'URL des métadonnées de la réponse.
Vos retours sur cette proposition de standard peuvent être envoyés à la mailing list OData.