Skip to content

Commit cda8b77

Browse files
committed
Added project documentation.
1 parent f0561e7 commit cda8b77

File tree

8 files changed

+120
-16
lines changed

8 files changed

+120
-16
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ Release v1.1.1
44

55
**Full Changelog**: https://github.com/ksbrwsk/reactive-people-postgresql/compare/1.0.2...v1.1.1
66

7-
## What’s Changed
7+
Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
package de.ksbrwsk.people;
22

3+
/**
4+
* This class contains constants that are used throughout the application.
5+
*/
36
public class Constants {
7+
/**
8+
* The base API endpoint for all people-related operations.
9+
*/
410
public static final String API = "/api/people";
5-
}
11+
}

src/main/java/de/ksbrwsk/people/PeopleApplication.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@
66
import org.springframework.boot.autoconfigure.SpringBootApplication;
77
import org.springframework.data.r2dbc.repository.config.EnableR2dbcRepositories;
88

9+
/**
10+
* This is the main class for the PeopleApplication.
11+
* It uses the @SpringBootApplication annotation to enable auto-configuration and component scanning.
12+
* It also uses the @EnableR2dbcRepositories annotation to enable the creation of reactive repositories.
13+
* The @OpenAPIDefinition annotation is used to provide metadata for the OpenAPI documentation.
14+
*/
915
@SpringBootApplication
1016
@EnableR2dbcRepositories
1117
@OpenAPIDefinition(info = @Info(
@@ -15,8 +21,11 @@
1521
))
1622
public class PeopleApplication {
1723

24+
/**
25+
* The main method that starts the application.
26+
* @param args The command line arguments.
27+
*/
1828
public static void main(String[] args) {
1929
SpringApplication.run(PeopleApplication.class, args);
2030
}
21-
22-
}
31+
}
Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,43 @@
11
package de.ksbrwsk.people;
22

33
import io.swagger.v3.oas.annotations.media.Schema;
4-
import jakarta.validation.constraints.NotNull;
4+
import jakarta.validation.constraints.NotBlank;
55
import jakarta.validation.constraints.Size;
66
import lombok.AllArgsConstructor;
77
import lombok.Data;
88
import lombok.NoArgsConstructor;
99
import org.springframework.data.annotation.Id;
1010

11+
/**
12+
* This class represents a Person entity.
13+
* It includes validation and API documentation annotations.
14+
*/
1115
@Data
1216
@NoArgsConstructor
1317
@AllArgsConstructor
1418
public class Person {
19+
/**
20+
* The unique identifier of the person.
21+
* It is automatically generated.
22+
*/
1523
@Id
1624
@Schema(name = "id", description = "The person's id")
1725
private Long id;
1826

19-
@NotNull
27+
/**
28+
* The name of the person.
29+
* It cannot be blank and its size must be between 1 and 10 characters.
30+
*/
31+
@NotBlank
2032
@Size(min = 1, max = 10)
2133
@Schema(minLength = 1, maxLength = 10, nullable = false, name = "name", description = "The person's name")
2234
private String name;
2335

36+
/**
37+
* Constructor that sets the name of the person.
38+
* @param name The name of the person.
39+
*/
2440
public Person(String name) {
2541
this.name = name;
2642
}
27-
}
43+
}

src/main/java/de/ksbrwsk/people/PersonHandler.java

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,32 @@
2323
import static org.springframework.web.reactive.function.BodyInserters.fromValue;
2424
import static org.springframework.web.reactive.function.server.ServerResponse.*;
2525

26+
/**
27+
* This class is responsible for handling HTTP requests related to the Person entity.
28+
* It includes methods for CRUD operations and finding a person by name.
29+
*/
2630
@Component
2731
@RequiredArgsConstructor
2832
@Slf4j
2933
public class PersonHandler {
3034
private final PersonRepository personRepository;
3135
private final Validator validator;
3236

37+
/**
38+
* Handles a request to get all persons.
39+
* @param serverRequest The incoming server request.
40+
* @return A ServerResponse with the list of all persons.
41+
*/
3342
public Mono<ServerResponse> handleFindAll(ServerRequest serverRequest) {
3443
return ok()
3544
.body(this.personRepository.findAll(), Person.class);
3645
}
3746

47+
/**
48+
* Handles a request to get a person by id.
49+
* @param serverRequest The incoming server request.
50+
* @return A ServerResponse with the person found or a 404 status if not found.
51+
*/
3852
public Mono<ServerResponse> handleFindById(ServerRequest serverRequest) {
3953
var id = Long.parseLong(serverRequest.pathVariable("id"));
4054
return this.personRepository.findById(id)
@@ -43,6 +57,11 @@ public Mono<ServerResponse> handleFindById(ServerRequest serverRequest) {
4357
.switchIfEmpty(notFound().build());
4458
}
4559

60+
/**
61+
* Handles a request to get the first person found by name.
62+
* @param serverRequest The incoming server request.
63+
* @return A ServerResponse with the person found or a 404 status if not found.
64+
*/
4665
public Mono<ServerResponse> handleFindFirstByName(ServerRequest serverRequest) {
4766
log.info("Handle request {} {}", serverRequest.method(), serverRequest.path());
4867
var name = serverRequest.pathVariable("name");
@@ -53,6 +72,11 @@ public Mono<ServerResponse> handleFindFirstByName(ServerRequest serverRequest) {
5372
.switchIfEmpty(notFound);
5473
}
5574

75+
/**
76+
* Handles a request to delete a person by id.
77+
* @param serverRequest The incoming server request.
78+
* @return A ServerResponse with a success message or a 404 status if not found.
79+
*/
5680
public Mono<ServerResponse> handleDeleteById(ServerRequest serverRequest) {
5781
var id = Long.parseLong(serverRequest.pathVariable("id"));
5882
return this.personRepository.findById(id)
@@ -64,6 +88,11 @@ public Mono<ServerResponse> handleDeleteById(ServerRequest serverRequest) {
6488
.bodyValue(msg));
6589
}
6690

91+
/**
92+
* Handles a request to create a new person.
93+
* @param serverRequest The incoming server request.
94+
* @return A ServerResponse with the created person or a 400 status if the request body is invalid.
95+
*/
6796
public Mono<ServerResponse> handleCreate(ServerRequest serverRequest) {
6897
return serverRequest.bodyToMono(Person.class)
6998
.switchIfEmpty(Mono.error(new ServerWebInputException("person must not be null")))
@@ -74,6 +103,11 @@ public Mono<ServerResponse> handleCreate(ServerRequest serverRequest) {
74103
.bodyValue(person));
75104
}
76105

106+
/**
107+
* Handles a request to update a person by id.
108+
* @param serverRequest The incoming server request.
109+
* @return A ServerResponse with the updated person or a 404 status if not found.
110+
*/
77111
public Mono<ServerResponse> handleUpdate(ServerRequest serverRequest) {
78112
var id = Long.parseLong(serverRequest.pathVariable("id"));
79113
final Mono<Person> update = serverRequest.bodyToMono(Person.class)
@@ -90,6 +124,11 @@ public Mono<ServerResponse> handleUpdate(ServerRequest serverRequest) {
90124
.switchIfEmpty(notFound().build());
91125
}
92126

127+
/**
128+
* Validates a person using the Validator.
129+
* @param person The person to validate.
130+
* @throws ServerWebInputException If the person is not valid.
131+
*/
93132
private void validate(Person person) {
94133
Set<ConstraintViolation<Person>> violations = this.validator.validate(person);
95134
if (!violations.isEmpty()) {
@@ -101,9 +140,14 @@ private void validate(Person person) {
101140
}
102141
}
103142

143+
/**
144+
* Formats a validation error.
145+
* @param personConstraintViolation The validation error.
146+
* @return A string representation of the validation error.
147+
*/
104148
private String formatError(ConstraintViolation<Person> personConstraintViolation) {
105149
String field = StringUtils.capitalize(personConstraintViolation.getPropertyPath().toString());
106150
String error = personConstraintViolation.getMessage();
107151
return String.format("%s - %s", field, error);
108152
}
109-
}
153+
}

src/main/java/de/ksbrwsk/people/PersonRepository.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,21 @@
33
import org.springframework.data.repository.reactive.ReactiveCrudRepository;
44
import reactor.core.publisher.Mono;
55

6+
/**
7+
* This interface represents a repository for the Person entity.
8+
* It extends the ReactiveCrudRepository interface provided by Spring Data.
9+
*/
610
public interface PersonRepository extends ReactiveCrudRepository<Person, Long> {
11+
/**
12+
* This method returns the first Person found with the given name.
13+
* @param name The name of the Person to search for.
14+
* @return A Mono that emits the found Person or completes without emitting any items if no Person is found.
15+
*/
716
Mono<Person> findFirstByName(String name);
817

18+
/**
19+
* This method returns the Person with the lowest id.
20+
* @return A Mono that emits the found Person or completes without emitting any items if no Person is found.
21+
*/
922
Mono<Person> findTopByOrderByIdAsc();
10-
}
23+
}

src/main/java/de/ksbrwsk/people/PersonRouter.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,19 @@
2222
import static org.springframework.web.reactive.function.server.RouterFunctions.nest;
2323
import static org.springframework.web.reactive.function.server.RouterFunctions.route;
2424

25+
/**
26+
* This class is responsible for routing HTTP requests to the appropriate handler methods.
27+
* It uses Spring's functional routing style with RouterFunctions and RequestPredicates.
28+
*/
2529
@Configuration
2630
public class PersonRouter {
31+
/**
32+
* This method defines the routes for the Person API.
33+
* It uses the @RouterOperations annotation to provide OpenAPI documentation for each route.
34+
*
35+
* @param personHandler The handler class that contains the methods to handle the requests.
36+
* @return A RouterFunction that routes requests to the appropriate handler methods.
37+
*/
2738
@Bean
2839
@RouterOperations(
2940
{

src/test/java/de/ksbrwsk/people/PersonTest.java

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,9 @@
77
import org.junit.jupiter.params.provider.ValueSource;
88
import org.springframework.beans.factory.annotation.Autowired;
99
import org.springframework.boot.test.context.SpringBootTest;
10-
import org.springframework.boot.test.context.TestConfiguration;
1110
import org.springframework.test.context.TestPropertySource;
1211

13-
import static org.junit.jupiter.api.Assertions.assertEquals;
14-
import static org.junit.jupiter.api.Assertions.assertFalse;
12+
import static org.assertj.core.api.Assertions.assertThat;
1513

1614
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
1715
@TestPropertySource(properties = {"spring.autoconfigure.exclude=" +
@@ -23,18 +21,25 @@ class PersonTest {
2321
@Test
2422
void should_create_person() {
2523
Person person = new Person(1L, "Name");
26-
assertEquals(person.getId(), 1L);
27-
assertEquals(person.getName(), "Name");
24+
assertThat(person.getId()).isEqualTo(1L);
25+
assertThat(person.getName()).isEqualTo("Name");
2826
}
2927

28+
@ParameterizedTest
29+
@ValueSource(strings = {"N", "Name", "0123456789"})
30+
void should_create_valid_person(String name) {
31+
Person person = new Person(name);
32+
var violations = this.validator.validate(person);
33+
assertThat(violations).isEmpty();
34+
}
3035

3136
@ParameterizedTest
3237
@NullAndEmptySource
3338
@ValueSource(strings = {"01234567890"})
34-
void notValid(String name) {
39+
void should_create_invalid_person(String name) {
3540
Person person = new Person(name);
3641
var violations = this.validator.validate(person);
37-
assertFalse(violations.isEmpty());
42+
assertThat(violations).isNotEmpty();
3843
violations.forEach(System.out::println);
3944
}
4045
}

0 commit comments

Comments
 (0)