web-dev-qa-db-fra.com

Dois-je retourner une réponse 204 ou 404 lorsqu'une ressource n'est pas trouvée?

Je développe un service RESTful simple pour les tournois et les horaires. Lorsqu'un tournoi est créé via une requête POST contenant un corps JSON, le tournoi est inséré dans un BiMap, déclaré comme suit dans une implémentation DAO:

private BiMap<String, Tournament> tournaments = Maps.synchronizedBiMap(HashBiMap.create());

Lorsqu'un tournoi est créé, son identifiant de chaîne associé est renvoyé afin que tilisateur puisse avoir une référence future de ce tournoi. Il/elle peut obtenir des informations du nouveau tournoi en effectuant la demande suivante:

GET http://localhost:8080/eventscheduler/c15268ce-474a-49bd-a623-b0b865386f39

Mais que se passe-t-il si aucun tournoi avec un tel identifiant n'est trouvé? Jusqu'à présent, je retourne une réponse 204. Eh bien, Jersey le fait pour moi en retournant null à partir d'une de ses méthodes. C'est la méthode qui correspond à l'itinéraire ci-dessus:

@Path("/{id}")
@GET
@Produces(MediaType.APPLICATION_JSON)
public Tournament getTournament(@PathParam("id") String id) {
    Optional<Tournament> optTournament = tournamentDao.getTournament(id);
    if (optTournament.isPresent())
        return optTournament.get();
    return null;
}

Ma question est: est-il OK de retourner un 204: No Content réponse, ou doit-il s'agir d'une 404 réponse à la place, car la ressource est introuvable?

Si je devais le changer en 404, question évidente: devrais-je changer la signature de la méthode non? Etant donné qu'un tournoi (de type Tournament) peut ne plus être retourné, la méthode devrait être différente. Dois-je plutôt utiliser le type Response comme type de retour?

15
dabadaba

HTTP 204 Signifie que quelque chose était trouvé, mais il est vide. Par exemple, imaginez que vous ' re service des fichiers journaux via HTTP, avec les demandes telles que http://example.com/logs/ [date-go-here] . Le 18 mai 2015:

  • http://example.com/logs/2015-05-19 renverrait HTTP 404, ce qui signifie qu'il n'y a pas de journaux, car, eh bien, il est difficile d'enregistrer l'avenir.

  • http://example.com/logs/2015-05-18 , cependant, renverrait soit HTTP 200 avec les entrées de journal dans le contenu de la réponse, soit HTTP 204 si le fichier journal a été créé, mais aucun journal n'a encore été enregistré pour cette date.

Si vous fournissez null au framework en réponse à une demande, cela suppose que vous avez trouvé une entrée, et cette entrée est vide, donc HTTP 204. Au lieu de cela, vous devez throw new NotFoundException(); pour indiquer au framework que l'entrée n'existe pas, afin qu'elle génère un HTTP 404.

Si je devais le changer en 404, question évidente: devrais-je changer la signature de la méthode non?

Non, non. C'est la bonne chose à propos de throw new NotFoundException();. Cela fonctionnera quel que soit le type de retour réel de votre méthode.

32
Arseni Mourzenko

Vous devez renvoyer un 404. Vous pouvez le faire en lançant une NotFoundException ( https://jersey.Java.net/apidocs/2.6/jersey/javax/ws/rs/NotFoundException.html ).

Veuillez également consulter cette SO question si vous devez contrôler le type de contenu renvoyé https://stackoverflow.com/questions/23858488/how-i-return-http-404 -json-xml-response-in-jax-rs-jersey-on-Tomcat

3
Chamindu

Votre demande est GET http://localhost:8080/eventscheduler/c15268ce-474a-49bd-a623-b0b865386f39.

Si http://localhost:8080/eventscheduler/ n'existe pas en tant que point de terminaison, vous devez renvoyer un 404. Vous essayez d'accéder à une ressource (/eventscheduler/) qui n'existe pas. Cela indiquerait à un client qu'un serveur existe sur localhost:8080, mais il n'y a rien au point de terminaison eventscheduler.

Si http://localhost:8080/eventscheduler/ existe en tant que point de terminaison mais les ressources requises ne sont pas disponibles, une erreur 5xx est appropriée. Un bon exemple de cela serait si une base de données est hors ligne, où vous pouvez retourner un 503. Bien sûr, vous pouvez simplement retourner une erreur générique 500 au lieu d'une instance spécifique.

Si http://localhost:8080/eventscheduler/ existe mais la chose représentée par c15268ce-474a-49bd-a623-b0b865386f39 n'existe pas, je retournerais un 200 avec un corps indiquant les détails. Le point de terminaison existe, la demande effectuée était totalement valide et pouvait être traitée, mais il n'y avait aucune correspondance.

Si la demande de votre client au point de terminaison n'était pas valide, vous examineriez les autres erreurs 4xx. Vous pouvez indiquer que le client n'est pas autorisé à accéder au point de terminaison ou aux éléments demandés avec un 401 ou 403 ou pouvez utiliser un 400 pour indiquer que la demande n'est pas valide. Avec n'importe lequel de ces éléments, des informations supplémentaires peuvent être fournies dans le corps de réponse.

1
Thomas Owens