# Effortless API Documentation in Spring Boot with OpenAPI

When designing an API, we make many frontend decisions such as response structure, pagination strategy, and error handling. We can capture these design choices using an API description language—and OpenAPI is one of the most widely used descriptor languages for REST APIs.

OpenAPI (formerly Swagger) has become the industry standard for describing APIs, making them easier to understand, document, and consume.

At its core, OpenAPI defines an API’s structure in a **machine-readable format** (YAML or JSON). For example, a simple OpenAPI definition for retrieving blog posts might look like this:

```yaml
openapi: 3.0.1
info:
  title: Blog API
  version: 1.0.0
paths:
  /posts:
    get:
      summary: Get all posts
      responses:
        "200":
          description: Successfully retrieved list
```

With OpenAPI, you can **automate API documentation, generate client SDKs, and improve developer experience**.

For Spring Boot projects, we can use the ***springdoc-openapi*** library, which automatically generates API documentation by scanning Spring configurations, class structures, and annotations at runtime.

With just a simple setup, you can hit the ground running. Let’s get started! 🚀

## **Getting started**  

To integrate Spring Boot with OpenAPI, simply add the springdoc-openapi library to your project dependencies—no additional configuration is needed!

📌 **Add the dependency to pom.xml**

```xml
<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
    <version>2.3.0</version>
</dependency>
```

  
Restart your Spring Boot application, and now you can access Swagger UI, which displays all of your endpoints in an interactive format.

📌 **Visit Swagger UI:**

[**http://localhost:8080/swagger-ui.html**](http://localhost:8080/swagger-ui.html)

![](https://lh7-rt.googleusercontent.com/docsz/AD_4nXfLmtgbsVHSwCEPFSUnzzvB_IuO4i61y_KoQw1F_MleiKaddHOk50N6QrgfRgRpPTWyFCheC0XyIX8lN2JFDKeYHHwZQ-KrrZsJ4xcqHeR5IEOQlkuEc_DkxCIs2YwVKUZl2_Ok4A?key=okvipj2WfArLAjKm6XLljots align="left")

In addition, after starting your Spring Boot project, Springdoc automatically generates an **OpenAPI definition** based on your controllers and annotations.

📌 **You can view the raw OpenAPI spec at:**

[http://localhost:8080/v3/api-docs](http://localhost:8080/v3/api-docs)

## Enhancing API Documentation:

This initial setup is great, but to make the API more **developer-friendly**, we should **add more details** using annotations.

For example, let’s document the GET /posts endpoint:

```java
@GetMapping
@Operation(
    summary = "Get all posts",
    description = "Retrieve a list of all posts",
    responses = {
        @ApiResponse(responseCode = "200", description = "Successfully retrieved list",
            content = @Content(mediaType = "application/json",
            schema = @Schema(implementation = PostDto.class))
        )
    }
)
public List<PostDto> getAllPosts() {

    return service.getAllPosts();

}

```

Now, **restart your Spring Boot application**, and you’ll see **detailed documentation** for this operation in Swagger UI:

![](https://lh7-rt.googleusercontent.com/docsz/AD_4nXerPNQ-o95ilJ1jD-jaNEiN6BmXsjXVDbOaylM4gyi5MHHYSyuH9BWPYevjAY1oW6gddRgl44aynLl8LOsQc0LA-45_xzPNRc2pStM-2jLEpGNt3BTNzZ8KnIzwb02e2IFWFsZdEQ?key=okvipj2WfArLAjKm6XLljots align="left")

### Troubleshooting: Swagger UI Not Updating?

Sometimes, Swagger UI caches old versions of your API. If your changes aren’t showing up, try these steps:

1️⃣ Clean and restart your app

2️⃣ Clear your browser cache or open Swagger UI in Incognito Mode.  
3️⃣ Manually refresh the API documentation:

* Go to [http://localhost:8080/v3/api-docs](http://localhost:8080/v3/api-docs) and refresh.
    
* Then reload [http://localhost:8080/swagger-ui.html](http://localhost:8080/swagger-ui.html).
    

## Key OpenAPI Annotations in Spring Boot

| **Annotation** | **Purpose** |
| --- | --- |
| `@Operation` | Describes API endpoints (summary, description) |
| `@Parameter` | Documents path/query parameters |
| `@RequestBody` | Describes JSON request bodies |
| `@ApiResponse` | Defines HTTP response codes |
| `@Schema` | Documents DTOs and fields |
| `@ExampleObject` | Provides sample request/response JSON |
| `@SecurityRequirement` | Documents authentication requirements |

Now, let’s see how each of these works in practice:

### 1️⃣ Documenting API Endpoints

### **🔹 @Operation (Defines API Endpoint Details)**

* Provides **summary**, **description**, and **tags** for an API method.
    

✅ **Example:**

```java
@GetMapping
@Operation(
    summary = "Get all posts",
    description = "Retrieve a list of all posts"
)
public List<PostDto> getAllPosts() {
    return service.getAllPosts();
}
```

---

### 2️⃣ Documenting Request Parameters

### **🔹 @Parameter (Describes Path and Query Parameters)**

* Adds metadata to **@PathVariable** or **@RequestParam**.
    

✅ **Example:**

```java
@GetMapping("/{id}")
@Operation(summary = "Get a post by ID")
public PostDto getPostById(
    @Parameter(description = "ID of the post", example = "1")
    @PathVariable long id
) {
    return service.getPostById(id);
}
```

---

### 3️⃣ Documenting Request Bodies

### **🔹 @RequestBody (Describes JSON Request Body)**

* Provides a **description** of the request body format.
    

✅ **Example:**

```java
@PostMapping
@Operation(summary = "Create a new post")
public ResponseEntity<PostDto> createPost(
    @io.swagger.v3.oas.annotations.parameters.RequestBody(
        description = "Post details",
        required = true
    )
    @Valid @RequestBody NewPostDto post
) {
    return ResponseEntity.status(201).body(service.createPost(post));
}
```

One use case for this is: When you need to support multiple content types (JSON, XML, etc)

---

### 4️⃣ Documenting API Responses

### **🔹 @ApiResponse (Describes Possible HTTP Responses)**

* Defines **response codes**, **descriptions**, and **schemas**.
    

✅ **Example:**

```java
@Operation(
    summary = "Delete a post",
    responses = {
        @ApiResponse(responseCode = "204", description = "Post deleted"),
        @ApiResponse(responseCode = "404", description = "Post not found")
    }
)
@DeleteMapping("/{id}")
public ResponseEntity<Void> deletePost(@PathVariable long id) {
    service.deletePost(id);
    return ResponseEntity.noContent().build();
}
```

---

### 5️⃣ Documenting Response Models

### **🔹 @Schema (Describes DTOs and Fields)**

* Used inside **DTO classes** to provide **descriptions and example values**.
    

✅ **Example:**

```java
@Schema(description = "DTO for creating a post")
public record NewPostDto(
    @Schema(description = "Title of the post", example = "My first post")
    String title,
    @Schema(description = "Content of the post", example = "This is a sample post")
    String content
) {}
```

---

### 6️⃣ Adding Example Values

### **🔹 @ExampleObject (Provides Sample JSON Data)**

* Used inside @Content to **show example request/response bodies**.
    

✅ **Example:**

```java
@ApiResponse(
responseCode = "200",
    description = "Post retrieved",
    content = @Content(
        mediaType = "application/json",
        examples = @ExampleObject(
            name = "Example Response",
            value = """
            {
                "id": 1,
                "title": "My first post",
                "content": "This is a sample post."
            }
            """
        )
    )
)
```

---

### 7️⃣ Securing APIs

### **🔹 @SecurityRequirement (Indicates Authentication Requirements)**

* Used to specify that an API requires **JWT or OAuth authentication**.
    

✅ **Example:**

```java
@Operation(
    summary = "Get user details",
    security = { @SecurityRequirement(name = "bearerAuth") }
)

@GetMapping("/user")
public UserDto getUserDetails() {
    return userService.getUserDetails();
}
```

![](https://lh7-rt.googleusercontent.com/docsz/AD_4nXcSmvUCp3C-_DxseLfJxRyIoWjssWq397S7xD-wKBZMNmLfK_fj1b8eXxb7aGaAE71SIpqgH0-C_qisTgAD9ivN2ub8jB6aQhbVjRvt2iknfC8hwxXFOocr-MPvKDbX8qIf8lCz5w?key=okvipj2WfArLAjKm6XLljots align="left")

## **🚀 Conclusion**

With OpenAPI and Springdoc, you can automate and simplify API documentation in your Spring Boot applications. Using annotations, you provide clear, structured, and interactive API docs—making it easier for developers to understand and use your API.

Now go ahead and document your Spring Boot API effortlessly! 🚀

## **📌 Explore More**

Want to see this in action? **Check out my project on GitHub:**🔗 [GitHub Repo](https://github.com/mdjc/blog-posts-app/commit/0c4af81ed10fcc4360a96bc759c8741ff869e92b)

### **Learn More:**

* 🔗 [Springdoc OpenAPI Docs](https://springdoc.org/)
    
* 🔗 [Baeldung: OpenAPI Documentation](https://www.baeldung.com/spring-rest-openapi-documentation)
    
* 🔗[OpenAPI Spec](https://spec.openapis.org/oas/latest.html#openapi-specification)
    
* 📖 *API Design* by Matthias Biehl
