536 votes

Comment concevoir la recherche/filtrage reposant ?

Je suis actuellement à la conception et à la mise en œuvre d'une API RESTful en PHP. Cependant, j'ai été en échec de la mise en œuvre de ma conception initiale.

GET /users # list of users
GET /user/1 # get user with id 1
POST /user # create new user
PUT /user/1 # modify user with id 1
DELETE /user/1 # delete user with id 1

Jusqu'à présent assez standard, à droite?

Mon problème est avec le premier GET /users. J'envisage l'envoi de paramètres dans le corps de la requête pour filtrer la liste. C'est parce que je veux être en mesure de spécifier des filtres complexes sans avoir une super longue url, comme:

GET /users?parameter1=value1&parameter2=value2&parameter3=value3&parameter4=value4

Au lieu de cela, je voulais avoir quelque chose comme:

GET /users
# Request body:
{
    "parameter1": "value1",
    "parameter2": "value2",
    "parameter3": "value3",
    "parameter4": "value4"
}

ce qui est beaucoup plus lisible et vous offre de grandes possibilités pour définir des filtres complexes.

De toute façon, file_get_contents('php://input') n'ont pas de retourner le corps de la requête pour GET des demandes. J'ai aussi essayé d' http_get_request_body(), mais l'hébergement mutualisé que j'utilise n'a pas de pecl_http. Pas sûr qu'il aurait été utile de toute façon.

J'ai trouvé cette question et a constaté que, probablement, n'est pas censé avoir un corps de la requête. C'était un peu concluants, mais ils déconseillées.

Alors maintenant, je ne suis pas sûr de quoi faire. Comment concevoir une bonne recherche/filterng fonction?

Je suppose que je pourrais utiliser POST, mais ça ne semble pas très Reposant.

442voto

Jason Harrelson Points 691

La meilleure façon de mettre en œuvre un séjour de recherche est de considérer que la recherche en elle-même comme une ressource. Ensuite, vous pouvez utiliser le verbe POST parce que vous êtes la création d'une recherche. Vous n'avez pas à littéralement créer quelque chose dans une base de données afin d'utiliser un POST.

Par exemple:

Accept: application/json
Content-Type: application/json
POST http://example.com/people/searches
{
  "terms": {
    "ssn": "123456789"
  },
  "order": { ... },
  ...
}

Vous créez une recherche de l'utilisateur du point de vue. Les détails de mise en œuvre de ce ne sont pas pertinents. Certains RESTful Api ne peuvent même pas besoin de la persistance. C'est un détail d'implémentation.

20voto

Daff Points 22358

Je pense que vous devriez aller avec les paramètres de la demande, mais seulement tant qu'il n'est pas approprié d'en-tête HTTP pour accomplir ce que vous voulez faire. La spécification HTTP, ne disent pas explicitement, que se ne peut pas avoir un corps. Toutefois, ce document stipule:

Par convention, lorsque la méthode GET est utilisé, toutes les informations nécessaires pour identifier la ressource est codé dans l' l'URI. Il n'y a pas de convention dans HTTP/1.1 pour une interaction sécuritaire (p. ex., la récupération des données) lorsque le client fournit les données sur le serveur en HTTP entité corps plutôt que dans la partie requête de un URI. Cela signifie que, pour sûr les opérations, les Uri peut être long.

1voto

luis.espinal Points 4145

Ne vous inquiétez pas trop si votre initiale de l'API est entièrement Reposante ou pas (spécialement quand vous êtes juste dans l'alpha étapes). Obtenir le back-end de plomberie à travailler d'abord. Vous pouvez toujours faire une sorte de URL de la transformation/ré-écriture de la carte les choses, de raffinage de manière itérative jusqu'à ce que vous obtenez quelque chose de stable assez généralisée d'essais ("bêta").

Vous pouvez définir les Uri dont les paramètres sont codés par la position et la convention sur l'Uri eux-mêmes, préfixé par un chemin, vous savez que vous aurez toujours une carte à quelque chose. Je ne connais pas PHP, mais je suppose qu'une telle structure existe (comme cela existe dans d'autres langues avec les frameworks web):

.c'est à dire. Faire un "utilisateur" type de recherche avec les param[i]=valeur[i] pour i=1..4 sur le magasin n ° 1:

1) GET /store1/search/user/value1,value2,value3,value4

ou

2) GET /store1/search/user,value1,value2,value3,value4

ou comme suit (même si je ne le recommanderais pas, plus sur cela plus tard)

3) GET /search/store1,user,value1,value2,value3,value4

Avec l'option 1, vous avez une carte de tous les Uri avec le préfixe /store1/search/user à la recherche de gestionnaire (ou quel que soit le PHP désignation) à défaut, de faire des recherches pour les ressources sous store1 (équivalent à /search?location=store1&type=user.

Par convention documenté et appliqué par l'API, des valeurs de paramètres 1 à 4 sont séparés par des virgules, et présentés dans l'ordre. Mauvais paramètre positions provoquera une erreur ou un comportement indéfini.

Option 2 ajoute le type de recherche (dans ce cas - user) comme paramètre de position #1. L'option est juste un choix de cosmétiques.

L'Option 3 est également possible, mais je ne pense pas que je le voudrais. Je pense que la capacité de la recherche à l'intérieur de certaines ressources doivent être présentés dans l'URI de lui-même, avant la recherche en elle-même (comme si en indiquant clairement dans l'URI que la recherche est spécifique au sein de la ressource.)

L'avantage de ce passage de paramètres de l'URI est que la recherche est une partie de l'URI (ainsi le traitement d'une recherche, une ressource, une ressource dont le contenu peut - et va - changer au fil du temps.) Le dissadvantage est que l'ordre des paramètres est obligatoire.

Une fois que vous faites quelque chose comme cela, vous pouvez utiliser OBTENIR, et ce serait une ressource en lecture seule (puisque vous ne pouvez pas le POST ou PUT - il est mis à jour lorsque c'est d'OBTENIR ed). Il serait également une ressource qui vient seulement d'exister lorsqu'elle est invoquée.

On pourrait également ajouter de la sémantique par la mise en cache des résultats pour une période de temps ou avec une SUPPRESSION provoquant le cache est supprimé. Toutefois, cela pourrait aller à l'encontre de ce que les gens utilisent généralement SUPPRIMER (et parce que les gens généralement contrôler la mise en cache avec la mise en cache des en-têtes.)

La façon dont vous aller à ce sujet serait une décision de conception, mais ce serait la façon dont j'allais parler. Il n'est pas parfait, et je suis sûr qu'il y aura des cas où ce n'est pas la meilleure chose à faire (spécialement pour les très complexes critères de recherche).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X