web-dev-qa-db-fra.com

Quelle est la bonne façon de faire une méthode de recherche RESTful complexe?

Suivant les principes REST, je voudrais créer une méthode GET pour mon API qui effectue une recherche en utilisant certains critères et renvoie les résultats au client. Le problème est que les critères peuvent avoir jusqu'à 14 paramètres, l'un d'eux est une liste d'objets complexes, donc ...

  • Je ne sais même pas s'il est possible de coder/décoder ces objets complexes vers/depuis les paramètres url.

  • Je n'ai pas calculé combien de temps l'URL pourrait avoir, mais je suis sûr qu'elle sera suffisamment grande et atteindra peut-être la limite de longueur d'URL?

De plus, la recherche devrait montrer les résultats en "temps réel", je veux dire, chaque fois que l'utilisateur change quelque chose du formulaire de recherche, il devrait pouvoir voir les nouveaux résultats sans appuyer sur aucun bouton "recherche".

Pourriez-vous me clarifier ces points et quel serait votre conseil pour créer une méthode de recherche reposante avec beaucoup de paramètres?

49
anat0lius

Avant de lire ma réponse, je voudrais dire que je suis d'accord avec @Neil. Nous devons choisir nos batailles. Nous voulons généralement faire de notre mieux, mais parfois il y a trop peu de place pour la discussion et nous devons prendre des décisions contre notre volonté.

Quoi qu'il en soit, dans la réponse de Neil, je manque encore une chose. Documentation . Juste pour s'assurer que les développeurs savent que POST demande à /search sont sûrs.

Cela dit.

1. Donnez une chance à GET

Considérez d'abord l'option GET. Consultez cette question longueur maximale de l'URL . Évaluez si votre chaîne de requête la plus longue dépasse 2 000 caractères. Si ce n'est pas le cas, et que vous ne vous y attendez pas, optez pour GET. Cela peut sembler laid mais il a tous les avantages dérivés de la sémantique de la méthode (idempotence, safe et cache). Et bookmarking.

1.1 Essayez d'encoder la chaîne de requête

Par exemple, en base 64. Même javascript supporte les encodages en base 64 .

Voici comment cela fonctionne:

  1. Construisez le JSON avec tous les filtres et normalisez-le.
  2. Analyser la chaîne
  3. Encode-le
  4. Envoyez le JSON encodé en tant que paramètre de demande (/search?q=SGVsbG8gV29ybGQh....).
  5. Côté serveur, décodez q.
  6. Désérialiser la chaîne JSON

Auparavant, créez la chaîne JSON la plus longue possible, encodez-la et prenez la longueur. Évaluez si la chaîne codée tient dans l'URL. J'ai implémenté l'extrait suivant sur Fiddle.js pour que vous puissiez le tester. (J'espère que ça marche toujours)1

Les codes de base 64 sont déterministes et réversibles, il n'y a donc aucune chance de collision.

Avec les requêtes codées, nous pourrions également enregistrer des recherches dans la base de données, mettre en signet l'URL, partager des liens, etc.

1.2 Essayez avec des alias

En lisant ceci blog sur la façon de concevoir REST, je me suis souvenu d'une autre alternative. Alias ​​pour les requêtes courantes .

Je trouve cela intéressant pour les prochaines raisons

  • Raccourcissez la longueur de la chaîne de requête. Il rend l'API plus propre et conviviale

    GET/tickets /? Status = closed & closedAt = xxx vs GET/tickets/récemment fermé /

  • Combinable avec plus d'alias ou plus de paramètres de requête.

    GET/tickets /? Status = closed & closedAt = xxx & within = 30min vs GET/tickets/récemment fermé /? Within = 30min

  • Nous pouvons combiner des alias avec des chaînes de requête codées

    GET/tickets /? Status = fermé & fermé At = xxx & within = 30min vs GET/tickets/récemment fermé /? Q = SGVsbG8g ...


1: J'ai utilisé JSON, mais nous pourrions utiliser d'autres formats dès que nous pourrons les désérialiser côté serveur.

63
Laiv

Si vous n'avez qu'un marteau, tout ressemble à un clou. Il semble que le problème ici soit que vous essayez de transformer une page de recherche en une page RESTful, et cela ne semble guère être un modèle commun à résoudre pour la conception RESTful.

Allez simplement avec une demande POST avec les paramètres fournis par l'utilisateur afin d'obtenir les informations dont vous avez besoin du backend. Je suppose que vous n'avez rien d'autre à faire qu'une recherche, donc il n'y a pas vous devrez peut-être insérer cette page. Ajoutez simplement une recherche/à la fin de votre URL afin de ne pas risquer de rencontrer des conflits avec votre page/users qui serait être RESTful.

14
Neil

Cela dépend entièrement de votre modèle d'API: comme aucun ou comme verbe.

Si l'API est un none, vous pouvez obtenir la liste des objets comme suit:

GET: /api/v1/objects

Dans ce cas, vous devez envoyer des données en tant que paramètres de demande. Vous devez donc décrire vos paramètres comme une liste plate de valeurs-clés:

GET: /api/v1/objects

key1 : val1
key2.key1 : val 21
key2.key2 : val 22
....

Certaines plates-formes prennent en charge le résolveur de paramètres personnalisé (par exemple Spring MVC), vous pouvez convertir des paramètres en un objet.

0
Mostafa