Skip to content

Commit 9ed8168

Browse files
committed
improved examples with annotations
1 parent 5b9f0c3 commit 9ed8168

10 files changed

+234
-23
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ npx bump-cli preview http://localhost:8080/openapi
2323

2424
Want to see how it will look without downloading anything? Take a look at this documentation [deployed with Bump.sh](https://bump.sh/bump-examples/hub/code-samples/doc/spring-code-first) already.
2525

26+
## Thanks
27+
28+
The sample code was inspired by https://github.com/spring-guides/tut-rest
29+
2630
## License
2731

2832
The contents of this repository are licensed under [CC BY-NC-SA

pom.xml

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,27 @@
3535
<artifactId>spring-boot-starter-web</artifactId>
3636
</dependency>
3737

38-
<dependency>
38+
<!-- This is all you need to add for OpenAPI -->
39+
<dependency>
3940
<groupId>org.springdoc</groupId>
4041
<artifactId>springdoc-openapi-starter-webmvc-api</artifactId>
4142
<version>2.8.8</version>
4243
</dependency>
44+
<!-- /end -->
45+
46+
<!-- some handy stuff you dont need for OpenAPI -->
47+
<dependency>
48+
<groupId>org.springframework.boot</groupId>
49+
<artifactId>spring-boot-starter-data-jpa</artifactId>
50+
</dependency>
51+
52+
<dependency>
53+
<groupId>com.h2database</groupId>
54+
<artifactId>h2</artifactId>
55+
<scope>runtime</scope>
56+
</dependency>
57+
<!-- /end -->
58+
4359
</dependencies>
4460

4561
<build>
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package com.bumpsh.demo;
2+
3+
import jakarta.persistence.Entity;
4+
import jakarta.persistence.GeneratedValue;
5+
import jakarta.persistence.Id;
6+
7+
import io.swagger.v3.oas.annotations.media.Schema;
8+
9+
@Entity
10+
@Schema(description = "Employees are individuals who work for an organization, " +
11+
"contributing their skills and expertise to achieve the organization's goals." +
12+
13+
"Roles are the specific functions or positions that employees occupy within the organization, " +
14+
"defining their duties, responsibilities, and the scope of their work."
15+
)
16+
class Employee {
17+
18+
private @Id
19+
20+
@Schema(accessMode = Schema.AccessMode.READ_ONLY, description = "Unique identifier which should not be shared publicly", example = "1234")
21+
@GeneratedValue Long id;
22+
23+
@Schema(description = "Employee name", example = "Bilbo Baggins")
24+
private String name;
25+
26+
@Schema(description = "Employee role", example = "Software Engineer")
27+
private String role;
28+
29+
Employee() {}
30+
31+
Employee(String name, String role) {
32+
this.name = name;
33+
this.role = role;
34+
}
35+
36+
public Long getId() {
37+
return this.id;
38+
}
39+
40+
public String getName() {
41+
return this.name;
42+
}
43+
44+
public String getRole() {
45+
return this.role;
46+
}
47+
48+
public void setId(Long id) {
49+
this.id = id;
50+
}
51+
52+
public void setName(String name) {
53+
this.name = name;
54+
}
55+
56+
public void setRole(String role) {
57+
this.role = role;
58+
}
59+
60+
// @Override
61+
// public boolean equals(Object o) {
62+
63+
// if (this == o)
64+
// return true;
65+
// if (!(o instanceof Employee))
66+
// return false;
67+
// Employee employee = (Employee) o;
68+
// return Objects.equals(this.id, employee.id) && Objects.equals(this.name, employee.name)
69+
// && Objects.equals(this.role, employee.role);
70+
// }
71+
72+
// @Override
73+
// public int hashCode() {
74+
// return Objects.hash(this.id, this.name, this.role);
75+
// }
76+
77+
// @Override
78+
// public String toString() {
79+
// return "Employee{" + "id=" + this.id + ", name='" + this.name + '\'' + ", role='" + this.role + '\'' + '}';
80+
// }
81+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package com.bumpsh.demo;
2+
3+
import java.util.List;
4+
5+
import org.springframework.web.bind.annotation.DeleteMapping;
6+
import org.springframework.web.bind.annotation.GetMapping;
7+
import org.springframework.web.bind.annotation.PathVariable;
8+
import org.springframework.web.bind.annotation.PostMapping;
9+
import org.springframework.web.bind.annotation.PutMapping;
10+
import org.springframework.web.bind.annotation.RequestBody;
11+
import org.springframework.web.bind.annotation.RestController;
12+
13+
import io.swagger.v3.oas.annotations.Operation;
14+
import io.swagger.v3.oas.annotations.enums.ParameterIn;
15+
import io.swagger.v3.oas.annotations.media.Content;
16+
import io.swagger.v3.oas.annotations.media.Schema;
17+
import io.swagger.v3.oas.annotations.responses.ApiResponses;
18+
import io.swagger.v3.oas.annotations.responses.ApiResponse;
19+
import io.swagger.v3.oas.annotations.tags.Tag;
20+
import io.swagger.v3.oas.annotations.Parameter;
21+
22+
@RestController
23+
@Tag(name = "Employee Management", description = "Operations related to employee management")
24+
class EmployeeController {
25+
26+
private final EmployeeRepository repository;
27+
28+
EmployeeController(EmployeeRepository repository) {
29+
this.repository = repository;
30+
}
31+
32+
// Aggregate root
33+
@GetMapping("/employees")
34+
@Operation(summary = "Get all employees", description = "Returns a list of all employees")
35+
List<Employee> all() {
36+
return repository.findAll();
37+
}
38+
39+
@PostMapping("/employees")
40+
@Operation(summary = "Create a new employee", description = "Adds a new employee to the system")
41+
Employee newEmployee(@RequestBody Employee newEmployee) {
42+
return repository.save(newEmployee);
43+
}
44+
45+
@GetMapping("/employees/{id}")
46+
@Operation(summary = "Get an employee by ID", description = "Returns the details of an employee based on the provided ID")
47+
@ApiResponse(
48+
responseCode = "200",
49+
description = "Successful operation",
50+
content = @Content(mediaType = "application/json",
51+
schema = @Schema(implementation = Employee.class))
52+
)
53+
public Employee one(
54+
@Parameter(in = ParameterIn.PATH, description = "ID of the employee to retrieve", required = true, schema = @Schema(type = "integer"))
55+
@PathVariable Long id) {
56+
return repository.findById(id)
57+
.orElseThrow(() -> new EmployeeNotFoundException(id));
58+
}
59+
60+
@PutMapping("/employees/{id}")
61+
@Operation(summary = "Update an existing employee", description = "Updates the details of an employee based on the provided ID")
62+
Employee replaceEmployee(@RequestBody Employee newEmployee, @PathVariable Long id) {
63+
return repository.findById(id)
64+
.map(employee -> {
65+
employee.setName(newEmployee.getName());
66+
employee.setRole(newEmployee.getRole());
67+
return repository.save(employee);
68+
})
69+
.orElseGet(() -> {
70+
return repository.save(newEmployee);
71+
});
72+
}
73+
74+
@DeleteMapping("/employees/{id}")
75+
@Operation(summary = "Delete an employee", description = "Removes an employee from the system based on the provided ID")
76+
void deleteEmployee(@PathVariable Long id) {
77+
repository.deleteById(id);
78+
}
79+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.bumpsh.demo;
2+
3+
import org.springframework.http.HttpStatus;
4+
import org.springframework.web.bind.annotation.ExceptionHandler;
5+
import org.springframework.web.bind.annotation.ResponseStatus;
6+
import org.springframework.web.bind.annotation.RestControllerAdvice;
7+
8+
@RestControllerAdvice
9+
class EmployeeNotFoundAdvice {
10+
11+
@ExceptionHandler(EmployeeNotFoundException.class)
12+
@ResponseStatus(HttpStatus.NOT_FOUND)
13+
String employeeNotFoundHandler(EmployeeNotFoundException ex) {
14+
return ex.getMessage();
15+
}
16+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package com.bumpsh.demo;
2+
3+
class EmployeeNotFoundException extends RuntimeException {
4+
5+
EmployeeNotFoundException(Long id) {
6+
super("Could not find employee " + id);
7+
}
8+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.bumpsh.demo;
2+
3+
import org.springframework.data.jpa.repository.JpaRepository;
4+
5+
interface EmployeeRepository extends JpaRepository<Employee, Long> {
6+
7+
}

src/main/java/com/bumpsh/demo/Greeting.java

Lines changed: 0 additions & 3 deletions
This file was deleted.

src/main/java/com/bumpsh/demo/GreetingController.java

Lines changed: 0 additions & 19 deletions
This file was deleted.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.bumpsh.demo;
2+
3+
import org.slf4j.Logger;
4+
import org.slf4j.LoggerFactory;
5+
import org.springframework.boot.CommandLineRunner;
6+
import org.springframework.context.annotation.Bean;
7+
import org.springframework.context.annotation.Configuration;
8+
9+
@Configuration
10+
class LoadDatabase {
11+
12+
private static final Logger log = LoggerFactory.getLogger(LoadDatabase.class);
13+
14+
@Bean
15+
CommandLineRunner initDatabase(EmployeeRepository repository) {
16+
17+
return args -> {
18+
log.info("Preloading " + repository.save(new Employee("Bilbo Baggins", "burglar")));
19+
log.info("Preloading " + repository.save(new Employee("Frodo Baggins", "thief")));
20+
};
21+
}
22+
}

0 commit comments

Comments
 (0)