REST API filter meilleure pratique de l'opérateur

je construis une API REST qui utilise un filter paramètre pour contrôler les résultats de recherche. Par exemple, on peut rechercher un utilisateur en appelant:

GET /users/?filter=name%3Dfoo

maintenant, mon API devrait permettre beaucoup de différents filter les opérateurs. les opérateurs Numériquesequals,greater than,less than,opérateurs de chaînescontains,begins with ou ends with et date opérateursyear of ou timediff. En outre, AND et OR combinaisons doivent être possible.

Fondamentalement, je veux soutenir un sous-ensemble des opérateurs de base de données MySQL sous-jacents.

j'ai trouvé beaucoup d'implémentations différentes (deux bons exemples sont Google Analytics et LongJump) qui semblent utiliser la syntaxe personnalisés.

En regardant mes exigences, Je concevrais probablement une syntaxe personnalisée assez similaire à la syntaxe de L'opérateur MySQL.

Cependant, je me demandais s'il y a des meilleurs pratiques établies que je devrais suivre et si je dois envisager autre chose. Merci!

23
demandé sur Horen 2014-09-29 20:18:41

4 réponses

Vous avez besoin d'un langage de requête, n'essayez pas de réinventer la roue! Par le repos c'est compliqué et pas entièrement résolu question. Il y a des contraintes de repos que votre application doit respecter:

  • interface uniforme / hypermédia comme le moteur de l'état de l'application:

    Vous devez envoyer des réponses hypermédia à vos clients, et ils doivent suivre les hyperliens donnés dans ces réponses, au lieu de construire les demandes sur leur propre. Si vous peut découpler les clients de la structure de L'URI.

  • interface unique / auto-descriptif de messages:

    Vous devez envoyer des messages annotés de sémantique. Vous pouvez donc découpler les clients de la structure des données. La meilleure solution pour ce faire est RDF avec par exemple open linked data vocabs. Si vous ne voulez pas utiliser RDF, alors la deuxième meilleure solution pour utiliser un type MIME spécifique au vendeur, de sorte que vos messages seront auto-descriptifs, mais les clients besoin de savoir comment analyser votre type MIME personnalisé.

pour décrire des liens de recherche simples, vous pouvez utiliser URI templates, par exemple GET /users/{?name} attendre name paramètre dans la chaîne de requête. Vous pouvez utiliser le hydra:IRITemplateMapping hydra vocab pour ajouter de la sémantique à la paramers comme name.

décrire des requêtes ad hoc est une tâche difficile. Vous devez décrire en quelque sorte ce que votre requête peut contenir.

  • vous pouvez choisir un langage de requête URI et vous en tenir aux modèles URI et probablement à l'annotation hydra. Il y a beaucoup de déjà existant URI de la requête langues, comme HTSQL,requête OData (ppl n'aime pas ça), etc...

  • vous pouvez choisir un langage de requête existant et l'envoyer dans un URI simple param. Cela peut être tout ce que vous voulez, par exemple SQL, SPARQL, etc... Vous devez enseigner votre client pour générer ce param. Vous pouvez créer votre propre vocabulaire pour décrire les contraintes de la requête réelle. Si vous n'avez pas besoin de choses compliquées, cela ne devrait pas être un problème. Je ne sais pas si une structure de requête existe déjà, mais je ne les ai jamais cherchées...

  • vous pouvez choisir un langage de requête existant et l'envoyer dans le corps dans un demande de recherche. Afaik SEARCH n'est ni mise en cache ni prise en charge par de récents clients HTTP. Il a été défini par webdav. Vous pouvez décrire votre requête avec le type MIME approprié, et vous pouvez utiliser le même vocab que par la solution précédente.

  • vous pouvez utiliser une solution de requête RDF, par exemple un SPARQL endpoint, ou Triple motif fragments, etc... Ainsi, vos requêtes contiendront les métadonnées sémantiques, et non la description de votre lien. Par SPARQL vous n'avez pas besoin d'un triple stockage de données, vous pouvez traduire les requêtes côté serveur en SQL, ou tout ce que vous utilisez. Vous pouvez probablement utiliser SPIN pour décrire les contraintes de requête et des modèles de requête, mais c'est nouveau pour moi aussi. Il pourrait y avoir d'autres solutions pour décrire les structures de requête SPARQL...

donc pour résumer si vous voulez une VRAIE solution de repos, vous devez décrire à vos clients, comment ils peuvent construire les requêtes et quels paramètres, opérateurs logiques ils peuvent utiliser. Sans description de requête ils ne pourront pas générer par exemple un HTML formulaire pour l'utilisateur. Si vous ne voulez pas d'une solution de repos, puis choisir un langage de requête écrire un constructeur sur le client, écrire un analyseur sur le serveur et c'est tout.

14
répondu inf3rno 2014-09-29 18:30:02

The Open Data Protocol (OData)

Vous pouvez vérifier l' BreezeJs aussi et voyez comment ce protocole est implémenté pour le noeud.js + mongodb avec le module breeze-mongodb et pour un projet. net en utilisant L'API Web et Entiteframork avec Breeze.ContextProvider dll.

9
répondu sergio 2014-10-08 13:52:56

en adoptant un ensemble de délimiteurs communs et acceptés, la comparaison de l'égalité peut être mise en œuvre en straight-forward de la mode. Définir la valeur du paramètre filter query-string à une chaîne en utilisant those les délimiteurs créent une liste de paires nom / valeur qui peut être facilement analysée du côté du serveur et utilisée améliorer au besoin les recherches dans les bases de données. Vous pouvez utiliser les délimiteurs de votre choix dire ("|") pour séparer les filtres individuels phrases pour OU et ("&") pour séparer filtre phrases pour et et un double colon ("::") Pour séparer les noms et les valeurs. Cela fournit un ensemble unique-assez de délimiteurs pour soutenir la majorité des cas d'utilisation et crée un utilisateur lisible la chaîne de la requête de paramètre. Un exemple simple permettra de clarifier la technique. Supposons que nous voulons pour demander les utilisateurs avec le nom "Todd" qui vivent dans "Denver" et ont le titre de "Grand Poobah".

L'URI de requête, complet avec la chaîne de requête peut ressembler à ceci:

GET http://www.example.com/users?filter="nom::todd&ville: denver et titre::le grand poobah"

le délimiteur du double colon ("::") sépare le nom de la propriété de la valeur de comparaison, permettre à la valeur de comparaison de contenir des espaces-faciliter l'analyse du délimiteur par rapport à la valeur sur le serveur. Notez que les noms de propriétés dans les paires nom/valeur correspondent au nom des propriétés qui seraient rendu par le service dans la charge utile.

Cas la sensibilité est certainement l'objet de débats au cas par cas, mais en général, le filtrage fonctionne mieux lorsque la casse est ignorée. Vous pouvez également proposer des jokers au besoin en utilisant l'astérisque ("*") comme la partie valeur de la paire nom/valeur. Pour les requêtes qui exigent plus-que l'égalité simple ou des comparaisons de wild-card, l'introduction des opérateurs est nécessaire. Dans ce cas, les opérateurs eux-mêmes devraient faire partie de la valeur et être répartis sur le serveur côté, plutôt qu'une partie du nom de la propriété. Lorsque la fonctionnalité complexe de requête-langage-style est nécessaire, envisager d'introduire le concept de requête à partir de la requête du système de filtre de protocole de données ouvertes (OData) Spécification des options (http://www.odata.org/documentation/odata-version-4-0/)

3
répondu java_geek 2014-10-06 13:35:31

Il semble y avoir beaucoup de normes (OData), mais beaucoup sont assez compliqué en ce qu'ils introduisent une nouvelle syntaxe.

pour un simple multi-filtrage le format suivant évite de polluer le paramètre namespace tout en restant au sommet de la technologie web existante

GET /users?filter[name]=John&filter[title]=Manager

il est facilement lisible et sur les langues d'arrière-plan comme PHP le recevra comme un tableau de filtres à appliquer.

0
répondu Pascal_dher 2017-06-13 09:49:31