web-dev-qa-db-fra.com

Dans JAX RS, différences entre le retour de Response et Bean ou Collection of Beans (DTO)

Je travaille sur la construction d'une api REST. Ma question est, lorsque j'utilise Jersey, quelles sont les différences entre la création de mes services et le retour d'un objet Response ou le renvoi du bean ou de la collection. Je ne suis que soucieux de réussir les appels, je lance des exceptions appropriées pour les erreurs et les situations exceptionnelles.

Voici un exemple:

@Produces(MediaType.APPLICATION_JSON)
public Response search(FooBean foo){
    List<FooBean> results = bar.search(foo);
    return Response.ok(results).build();
}

vs.

@Produces(MediaType.APPLICATION_JSON)
public List<FooBean> search(FooBean foo){
    List<FooBean> results = bar.search(foo);
    return results;
}

J'ai vu les deux exemples utilisés, et je préférerais le deuxième scénario, juste pour faciliter la reconnaissance de la méthode de service. J'ai examiné les réponses à ces deux méthodes et elles semblent être identiques.

Pensées?

40
Half_Duplex

Les différences sont expliquées dans la spécification JAX-RS:

.3.3 Type de retour

Les méthodes de ressource PEUVENT renvoyer void, Response, GenericEntity ou un autre Java, ces types de retour sont mappés sur un corps d'entité de réponse comme suit:

vide
Résultats dans un corps d'entité vide avec un code d'état 204.

Réponse
Résultats dans un corps d'entité mappé à partir de la propriété d'entité de la réponse avec le code d'état spécifié par la propriété d'état de la réponse. Une valeur de retour nulle entraîne un code d'état 204. Si la propriété d'état de la réponse n'est pas définie: un code d'état 200 est utilisé pour une propriété d'entité non nulle et un code d'état 204 est utilisé si la propriété d'entité est nulle.

GenericEntity
Résultats dans un corps d'entité mappé à partir de la propriété Entity de GenericEntity. Si la valeur de retour n'est pas nulle, un code d'état 200 est utilisé, une valeur de retour nulle entraîne un code d'état 204.

Autre
Résultats dans un corps d'entité mappé à partir de la classe de l'instance retournée. Si la valeur de retour n'est pas nulle, un code d'état 200 est utilisé, une valeur de retour nulle entraîne un code d'état 204.

Les méthodes qui doivent fournir des métadonnées supplémentaires avec une réponse doivent renvoyer une instance de Response, la classe ResponseBuilder fournit un moyen pratique de créer une instance de réponse à l'aide d'un modèle de générateur.

Les beans "réguliers" sont mappés à peu près de la même manière que Response, à l'exception qu'un Response vous permet de définir des métadonnées supplémentaires (en-têtes de réponse, statut spécialisé, type de contenu spécialisé, etc). En ce qui concerne celui à utiliser, c'est à vous de décider - Response vous donne plus de flexibilité, mais les beans réguliers sont plus "auto-documentés".

36
Perception

Il n'y a pas de différence si vous voulez toujours retourner la réponse 200 - OK, intercepte et manipule toutes les exceptions qui peuvent se produire avant ou après que votre méthode retourne le résultat, avec des interceptions ou WebApplicationException. Ainsi, ces deux méthodes entraîneront les mêmes réponses.

La seule différence réside dans des scénarios spécifiques, comme le retour d'objets nuls ou la création d'objets, comme cet exemple:

@POST
@Consumes("application/json")
public Response post(String content) {
    URI createdUri = ...
    Object createdContent = create(content);
    return Response.created(createdUri).entity(createdContent).build();
}

Dans ce cas, le retour sera 201 - CREATED (Avec l'URI pour accéder à l'objet créé)

Donc, la méthode suivante:

@POST
@Consumes("application/json")
public Object post(String content) {
    URI createdUri = ...
    Object createdContent = create(content);
    return createdContent;
}

... renverra une réponse 200 - OK

Si vous ne vous souciez pas du statut de réponse que votre client recevra, vous pouvez utiliser n'importe quelle déclaration sans problème.

Source: Jersey .

8

Mon point de vue personnel, si la réponse contient DTO (Bean/Collection de beans), alors le service de repos doit toujours retourner DTO, mais pas l'objet Response.

La motivation: tôt ou tard, il vous sera demandé de faciliter l'utilisation du service de repos pour les clients, en fournissant api client de repos. Habituellement, vous devez extraire interfaces de repos pour cela, et les implémenter avec vos services de repos. Ces interfaces de repos sont utilisées par les clients de votre client de repos.

Et du point de vue du client, il y a une énorme différence entre le traitement DTO et la réponse simple. Si la réponse est utilisée, votre client est forcé:

  1. Vérifiez explicitement le code de réponse pour traiter la réponse réussie
  2. Gérer les erreurs, en vérifiant explicitement les codes
  3. Convertissez le corps de votre réponse en DTO par lui-même.

Ce qui signifie que la gestion de Response est très similaire au renvoi de codes d'erreur dans les méthodes, ce qui est considéré comme une très mauvaise pratique. Afin de gérer les erreurs en un seul endroit, des exceptions sont utilisées (je ne parle pas de FP façons de gérer les erreurs, ce qui est le meilleur).

Alors que pouvez-vous faire:

  1. Si une demande est traitée avec succès, convertissez vos données de service de repos en DTO/Bean et renvoyez-les.
  2. En cas d'échec de la validation ou de problème, lancez une exception dans votre service de repos. Peut-être qu'un défaut mappeur d'exceptions n'est pas bon pour vous, donc, vous devrez implémenter votre propre mappeur d'exceptions.

Donc, si vous pensez à l'avance, vous devez retourner DTO.

Un cas d'utilisation, lorsque la réponse ordinaire doit être renvoyée - lorsque vous exportez un fichier, par exemple. Il semble que JAX RS ne permette pas de renvoyer un objet InputStream. Pas sûr, il faut le vérifier.

L'autre cas d'utilisation a été signalé par @Perception, mais il s'agit plus d'une exception que d'une règle:

Les méthodes qui doivent fournir des métadonnées supplémentaires avec une réponse doivent renvoyer une instance de Response, la classe ResponseBuilder fournit un moyen pratique de créer une instance de réponse à l'aide d'un modèle de générateur.

Remarque: c'est une question générale pour JAX RS, ne dépend pas d'une implémentation exacte, comme Resteasy ou Jersey

2
Alexandr