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?
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.
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.
Par exemple, en base 64. Même javascript supporte les encodages en base 64 .
Voici comment cela fonctionne:
/search?q=SGVsbG8gV29ybGQh....
).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.
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.
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.
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.