Reputation: 2302
I've an HTTP client sending many POST
requests to a server. The server responds to all requests with 201 Created
and a response body. For my purposes, the response header is enough, as I'm only interested in the Location
header. I'd like to avoid that the server produces a response body in order to significantly decrease network traffic.
According to 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 [...]
..., thus, I assume, the server COULD also respond e.g. with 204 No Content
, omiting the body.
Therefore my question: Is it possible to construct a POST
request which makes the server respond with 204 No Content
or to omit the response body in another way?
Update 1: The server side is a Spring Data REST project and I'm free to configure it. I know that I could set RepositoryRestConfiguration#setReturnBodyOnCreate
to false
, but that would be overdone as it affects all incoming requests. Therefore, I'd prefer to make the decision on the client side.
Upvotes: 6
Views: 1627
Reputation: 2302
Based on Evert's and Bertrand's answers plus a bit of googling, I finally implemented the following interceptor in the Spring Data REST server:
@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;
}
});
}
}
It produces the following communication, which is good enough for my purposes:
> 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
I would like to share the bounty evenly, but this is not possible. It goes to Bertrand, as he came with an answer which guided me to the very implementation. Thanks for your help.
Upvotes: 0
Reputation: 4179
Can you try changing your client such that you
I understand that you may have difficulties at the client end to apply these changes. But, in the longer run, I believe this would be worth it.
Upvotes: 0
Reputation: 1976
There is no way to do it client side only as it is not natively implemented in Spring REST server.
Anyway, any client demand can be transformed as an extra custom header or a query parameter in the request.
A way could be to override default response handlers and detect custom header (implements Prefer: return=minimal
as suggested before for instance) and/or query param presence to trigger an empty response with a 204 status. This post may help you to figure it out.
Upvotes: 1
Reputation: 99851
There's no real lever you can pull from the client side to control if the server will respond with a body or not, unless the service you work with has a specific feature that allows this.
A header that a server might use is Prefer: return=minimal
but if the service doesn't explicitly document support for this, chances are low that this will work.
Really the only think you can do one the client is to:
This is a pretty 'drastic' thing but clients do use this mechanism for some cases and it does work. However, if the POST response body was somewhat small there's a chance that it's not really making a ton of difference because the response might already have been sent.
Upvotes: 4