J'ai un client HTTP qui envoie de nombreuses requêtes POST à un serveur. Le serveur répond à toutes les requêtes avec 201 Created et un corps de réponse. Pour mes besoins, l'en-tête de réponse est suffisant, car je ne suis intéressé que par l'en-tête Location. Je voudrais éviter que le serveur produise un corps de réponse afin de réduire considérablement le trafic réseau.

Conformément à la RFC 7231, ...

  [...] if one or more resources has been created on the origin server as a
  result of successfully processing a POST request, the origin server
  SHOULD send a 201 (Created) response containing a Location header [...]

..., donc, je suppose, le serveur POURRAIT également répondre par ex. avec 204 No Content, en omettant le corps.

Par conséquent ma question: est-il possible de construire une requête POST qui oblige le serveur à répondre par 204 No Content ou d'omettre le corps de la réponse d'une autre manière?

Mise à jour 1: Le côté serveur est un projet Spring Data REST et je suis libre de le configurer. Je sais que je pourrais définir RepositoryRestConfiguration#setReturnBodyOnCreate sur false, mais ce serait exagéré car cela affecte toutes les demandes entrantes. Par conséquent, je préfère prendre la décision du côté client.

6
aboger 20 nov. 2018 à 13:50

4 réponses

Meilleure réponse

Sur la base des réponses d'Evert et de Bertrand et d'un peu de recherche sur Google, j'ai finalement implémenté l'intercepteur suivant dans le serveur Spring Data REST:

@Configuration
class RepositoryConfiguration {

    @Bean
    public MappedInterceptor preferReturnMinimalMappedInterceptor() {
        return new MappedInterceptor(new String[]{"/**"}, new HandlerInterceptor() {
            @Override
            public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
                if ("return=minimal".equals(request.getHeader("prefer"))) {
                    response.setContentLength(0);
                    response.addHeader("Preference-Applied", "return=minimal"");
                }
                return true;
            }
        });
    }

}

Il produit la communication suivante, qui est assez bonne pour mes besoins:

> POST /versions HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.59.0
> Accept: */*
> Content-Type: application/json
> Prefer: return=minimal
> Content-Length: 123
>
> [123 bytes data]

...

< HTTP/1.1 201
< Preference-Applied: return=minimal
< ETag: "0"
< Last-Modified: Fri, 30 Nov 2018 12:37:57 GMT
< Location: http://localhost:8080/versions/1
< Content-Type: application/hal+json;charset=UTF-8
< Content-Length: 0
< Date: Fri, 30 Nov 2018 12:37:57 GMT

Je voudrais partager la prime de manière égale, mais ce n'est pas possible. Il revient à Bertrand, car il est venu avec une réponse qui m'a guidé jusqu'à la mise en œuvre même. Merci de votre aide.

0
aboger 30 nov. 2018 à 17:52

Pouvez-vous essayer de changer votre client de telle sorte que vous

  • a) Interrogez le serveur avec des requêtes HTTP HEAD au lieu de requêtes POST
  • b) Analysez les en-têtes de réponse. Il n'y a pas de corps de réponse pour les demandes HEAD car le but des demandes HEAD est très similaire à votre exigence
  • c) Effectuer les requêtes POST nécessaires uniquement lorsque cela est nécessaire

Je comprends que vous pourriez avoir des difficultés du côté client à appliquer ces changements. Mais, à plus long terme, je pense que cela en vaudrait la peine.

0
Ruchira Randana 30 nov. 2018 à 09:46

Il n'y a aucun moyen de le faire uniquement côté client car il n'est pas implémenté nativement dans le serveur Spring REST.

Quoi qu'il en soit, toute demande client peut être transformée en en-tête personnalisé supplémentaire ou en paramètre de requête dans la demande.

Un moyen pourrait être de remplace les gestionnaires de réponse par défaut et détecte l'en-tête personnalisé (implémente Prefer: return=minimal comme suggéré précédemment par exemple) et / ou la présence de paramètre de requête pour déclencher une réponse vide avec un statut 204. Ce message peut vous aider à le comprendre.

1
Bertrand 30 nov. 2018 à 08:33

Il n'y a pas de véritable levier que vous pouvez tirer du côté client pour contrôler si le serveur répondra avec un corps ou non, à moins que le service avec lequel vous travaillez dispose d'une fonctionnalité spécifique qui le permet.

Un en-tête qu'un serveur peut utiliser est Prefer: return=minimal mais si le service ne documente pas explicitement la prise en charge de cela, il y a peu de chances que cela fonctionne.

Vraiment, la seule chose que vous puissiez faire avec le client est de:

  1. Tuez la connexion TCP dès que vous avez les en-têtes de réponse
  2. Tuez le flux HTTP / 2 lorsque vous avez reçu les en-têtes.

C'est une chose assez «drastique», mais les clients utilisent ce mécanisme dans certains cas et cela fonctionne. Cependant, si le corps de la réponse POST était un peu petit, il est possible que cela ne fasse pas vraiment une tonne de différence car la réponse a peut-être déjà été envoyée.

4
Evert 23 nov. 2018 à 16:08