Spring Boot
ApiResponse
Empty Response
Rest API
Java Development

ApiResponse with empty response body Spring Boot

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In Spring Boot, an endpoint with no response body is completely normal for operations such as DELETE or some PUT actions. The key is to make the runtime behavior and the OpenAPI documentation agree, which usually means returning 204 No Content and documenting that response without a schema.

Runtime Behavior: Return No Body Explicitly

At the controller level, the cleanest pattern is ResponseEntity<Void> with HttpStatus.NO_CONTENT.

java
1import org.springframework.http.HttpStatus;
2import org.springframework.http.ResponseEntity;
3import org.springframework.web.bind.annotation.DeleteMapping;
4import org.springframework.web.bind.annotation.PathVariable;
5import org.springframework.web.bind.annotation.RestController;
6
7@RestController
8public class UserController {
9
10    @DeleteMapping("/users/{id}")
11    public ResponseEntity<Void> deleteUser(@PathVariable long id) {
12        // delete the resource here
13        return ResponseEntity.noContent().build();
14    }
15}

This communicates two things clearly:

  • the request succeeded
  • there is no response body to deserialize

You can also return void and annotate with @ResponseStatus(HttpStatus.NO_CONTENT), but ResponseEntity<Void> is often clearer when you want explicit control over headers and status.

Documenting Empty Bodies with @ApiResponse

When you use Swagger or OpenAPI annotations, do not document a response schema if the body is empty. For a 204 response, the description is enough.

java
1import io.swagger.v3.oas.annotations.Operation;
2import io.swagger.v3.oas.annotations.responses.ApiResponse;
3import io.swagger.v3.oas.annotations.responses.ApiResponses;
4
5@Operation(summary = "Delete a user")
6@ApiResponses({
7    @ApiResponse(responseCode = "204", description = "User deleted successfully"),
8    @ApiResponse(responseCode = "404", description = "User not found")
9})
10@DeleteMapping("/users/{id}")
11public ResponseEntity<Void> deleteUser(@PathVariable long id) {
12    return ResponseEntity.noContent().build();
13}

That tells the generated API documentation that the success response exists but intentionally has no payload.

When to Use 204 No Content

204 is appropriate when the client does not need a representation back. Typical examples:

  • successful DELETE
  • idempotent PUT where the client already knows the final state
  • action endpoints that only signal success

If the client does need new state, use 200 OK and return a body instead. For example, if a PUT recalculates fields and the client must see them immediately, 204 is less helpful.

The point is not to eliminate payloads. It is to use them only when they add value.

Avoid Fake Empty Payloads

Some codebases return an empty object or a wrapper like ApiResponse with null data just to satisfy a pattern:

java
return ResponseEntity.ok(new ApiResponse<>("deleted", null));

That works, but it changes the contract. The response is no longer empty. It now has a JSON body, and clients must parse it accordingly.

If your API standard requires envelope objects everywhere, document that honestly. But if the real intent is "no body," then a real 204 is cleaner and more idiomatic.

Error Responses Are Different

An endpoint may have an empty success body and still return structured error bodies. That is a common and sensible pattern.

java
1@ApiResponses({
2    @ApiResponse(responseCode = "204", description = "User deleted successfully"),
3    @ApiResponse(responseCode = "400", description = "Invalid request"),
4    @ApiResponse(responseCode = "404", description = "User not found"),
5    @ApiResponse(responseCode = "500", description = "Internal server error")
6})

If you have a standard error model, you can include content schemas for the error responses while leaving the 204 response body empty.

A Full Example

java
1import io.swagger.v3.oas.annotations.Operation;
2import io.swagger.v3.oas.annotations.responses.ApiResponse;
3import io.swagger.v3.oas.annotations.responses.ApiResponses;
4import org.springframework.http.ResponseEntity;
5import org.springframework.web.bind.annotation.DeleteMapping;
6import org.springframework.web.bind.annotation.PathVariable;
7import org.springframework.web.bind.annotation.RestController;
8
9@RestController
10public class DocumentController {
11
12    @Operation(summary = "Delete a document")
13    @ApiResponses({
14        @ApiResponse(responseCode = "204", description = "Document deleted"),
15        @ApiResponse(responseCode = "404", description = "Document not found")
16    })
17    @DeleteMapping("/documents/{id}")
18    public ResponseEntity<Void> deleteDocument(@PathVariable long id) {
19        boolean deleted = true; // replace with service call
20        if (!deleted) {
21            return ResponseEntity.notFound().build();
22        }
23        return ResponseEntity.noContent().build();
24    }
25}

This is simple, explicit, and aligned across controller logic and OpenAPI documentation.

Common Pitfalls

  • Returning 200 OK with no body when the operation semantically matches 204 No Content. Clients then have to guess whether an empty body was intentional.
  • Documenting a schema on a response that is supposed to have no content. This creates misleading OpenAPI output and confused client code.
  • Wrapping an empty success in a JSON envelope just to satisfy an internal pattern, then still describing it as an empty response. The runtime contract and docs no longer match.
  • Using void without being explicit about the status code. Spring may default to 200 OK unless you set the status deliberately.
  • Forgetting that error responses may still need a body even when the success path does not. Document success and failure independently.

Summary

  • In Spring Boot, use ResponseEntity<Void> with ResponseEntity.noContent().build() for a true empty success body.
  • Document 204 responses in @ApiResponse without a content schema when no payload is returned.
  • Use 204 only when the client does not need a response representation.
  • If you return an envelope object, the response is not empty and should be documented as such.
  • Keep runtime behavior and OpenAPI documentation aligned so clients know what to expect.

Course illustration
Course illustration

All Rights Reserved.