Skip to content

Commit c8f1d9e

Browse files
feat: add new DTOs to avoid loops when loading data
1 parent 63dac8a commit c8f1d9e

4 files changed

Lines changed: 123 additions & 24 deletions

File tree

src/main/java/com/vianavitor/simplelibrarygame/controller/BookReadHistoryController.java

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package com.vianavitor.simplelibrarygame.controller;
22

33
import com.vianavitor.simplelibrarygame.dto.ApiResponse;
4+
import com.vianavitor.simplelibrarygame.dto.response.BookReadHistoryResponse;
45
import com.vianavitor.simplelibrarygame.dto.response.UsersBookReadHistoryResponse;
56
import com.vianavitor.simplelibrarygame.model.Book;
67
import com.vianavitor.simplelibrarygame.model.BookReadHistory;
8+
import com.vianavitor.simplelibrarygame.model.Student;
79
import com.vianavitor.simplelibrarygame.service.BookReadHistoryService;
810
import jakarta.servlet.http.HttpServletRequest;
911
import org.springframework.beans.factory.annotation.Autowired;
@@ -21,21 +23,25 @@ public class BookReadHistoryController {
2123
@Autowired
2224
private BookReadHistoryService historyService;
2325

24-
@PostMapping
25-
public ResponseEntity<ApiResponse<Void>> register(@RequestBody BookReadHistory history, HttpServletRequest request) {
26-
historyService.register(history);
27-
ApiResponse<Void> response = ApiResponse.success(null, "Reading progress saved", request.getRequestURI());
28-
return ResponseEntity.status(HttpStatus.CREATED).body(response);
29-
}
26+
private BookReadHistoryResponse BookReadHistoryToDto(BookReadHistory history) {
27+
Book book = history.getBook();
28+
Student student = history.getUser();
3029

31-
@GetMapping
32-
public ResponseEntity<ApiResponse<BookReadHistory>> getById(@PathVariable Long id, HttpServletRequest request) {
33-
BookReadHistory result = historyService.getById(id);
34-
ApiResponse<BookReadHistory> response = ApiResponse.success(result, request.getRequestURI());
35-
return ResponseEntity.ok(response);
30+
return new BookReadHistoryResponse(
31+
history.getId(),
32+
new BookReadHistoryResponse.StudentInfo(
33+
student.getId(),
34+
student.getName()
35+
),
36+
new UsersBookReadHistoryResponse.BookInfo(
37+
book.getId(),
38+
book.getTitle()
39+
),
40+
history.getLastUpdate(), history.getLastPageRead()
41+
);
3642
}
3743

38-
private UsersBookReadHistoryResponse bookReadHistoryToDto(BookReadHistory history) {
44+
private UsersBookReadHistoryResponse bookReadHistoryToUsersDto(BookReadHistory history) {
3945
Book book = history.getBook();
4046

4147
return new UsersBookReadHistoryResponse(
@@ -48,27 +54,45 @@ private UsersBookReadHistoryResponse bookReadHistoryToDto(BookReadHistory histor
4854
);
4955
}
5056

57+
@PostMapping
58+
public ResponseEntity<ApiResponse<Void>> register(@RequestBody BookReadHistory history, HttpServletRequest request) {
59+
historyService.register(history);
60+
ApiResponse<Void> response = ApiResponse.success(null, "Reading progress saved", request.getRequestURI());
61+
return ResponseEntity.status(HttpStatus.CREATED).body(response);
62+
}
63+
64+
@GetMapping
65+
public ResponseEntity<ApiResponse<BookReadHistoryResponse>> getById(@PathVariable Long id, HttpServletRequest request) {
66+
BookReadHistory result = historyService.getById(id);
67+
ApiResponse<BookReadHistoryResponse> response = ApiResponse.success(this.BookReadHistoryToDto(result), request.getRequestURI());
68+
return ResponseEntity.ok(response);
69+
}
70+
5171
@GetMapping("/student/{studentId}")
5272
public ResponseEntity<ApiResponse<List<UsersBookReadHistoryResponse>>> getByStudent(@PathVariable Long studentId, HttpServletRequest request) {
5373
List<UsersBookReadHistoryResponse> list = historyService.getByStudent(studentId)
5474
.stream()
55-
.map(this::bookReadHistoryToDto)
75+
.map(this::bookReadHistoryToUsersDto)
5676
.toList();
5777

5878
ApiResponse<List<UsersBookReadHistoryResponse>> response = ApiResponse.success(list, request.getRequestURI());
5979
return ResponseEntity.ok(response);
6080
}
6181

6282
@GetMapping("/book/{bookId}")
63-
public ResponseEntity<ApiResponse<List<BookReadHistory>>> getByBook(@PathVariable Long bookId, HttpServletRequest request) {
64-
List<BookReadHistory> list = historyService.getByBook(bookId);
65-
ApiResponse<List<BookReadHistory>> response = ApiResponse.success(list, request.getRequestURI());
83+
public ResponseEntity<ApiResponse<List<BookReadHistoryResponse>>> getByBook(@PathVariable Long bookId, HttpServletRequest request) {
84+
List<BookReadHistoryResponse> list = historyService.getByBook(bookId)
85+
.stream()
86+
.map(this::BookReadHistoryToDto)
87+
.toList();
88+
89+
ApiResponse<List<BookReadHistoryResponse>> response = ApiResponse.success(list, request.getRequestURI());
6690
return ResponseEntity.ok(response);
6791
}
6892

6993
@GetMapping("/student/{studentId}/last")
7094
public ResponseEntity<ApiResponse<UsersBookReadHistoryResponse>> getLastByStudent(@PathVariable Long studentId, HttpServletRequest request) {
71-
UsersBookReadHistoryResponse last = this.bookReadHistoryToDto(
95+
UsersBookReadHistoryResponse last = this.bookReadHistoryToUsersDto(
7296
historyService.getByStudentTheLastOne(studentId)
7397
);
7498

src/main/java/com/vianavitor/simplelibrarygame/controller/StudentStatsController.java

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
import com.vianavitor.simplelibrarygame.dto.request.AddExperienceRequest;
55
import com.vianavitor.simplelibrarygame.dto.request.AverageReadingTimeRequest;
66
import com.vianavitor.simplelibrarygame.dto.request.SetCurrentBookRequest;
7+
import com.vianavitor.simplelibrarygame.dto.response.StudentStatsResponse;
8+
import com.vianavitor.simplelibrarygame.dto.response.UsersBookReadHistoryResponse;
9+
import com.vianavitor.simplelibrarygame.model.Book;
10+
import com.vianavitor.simplelibrarygame.model.BookReadHistory;
711
import com.vianavitor.simplelibrarygame.model.StudentStats;
812
import com.vianavitor.simplelibrarygame.service.StudentStatsService;
913
import jakarta.servlet.http.HttpServletRequest;
@@ -13,7 +17,6 @@
1317
import org.springframework.http.ResponseEntity;
1418
import org.springframework.web.bind.annotation.*;
1519

16-
import java.util.Map;
1720

1821
@RestController
1922
@RequestMapping("/api/stats")
@@ -22,17 +25,48 @@ public class StudentStatsController {
2225
@Autowired
2326
private StudentStatsService statsService;
2427

28+
private StudentStatsResponse studentStatsToDto(StudentStats stats) {
29+
BookReadHistory history = stats.getCurrentBook();
30+
UsersBookReadHistoryResponse userHistory = null;
31+
32+
if (history != null) {
33+
Book book = history.getBook();
34+
35+
userHistory = new UsersBookReadHistoryResponse(
36+
history.getId(),
37+
new UsersBookReadHistoryResponse.BookInfo(
38+
book.getId(),
39+
book.getTitle()
40+
),
41+
history.getLastUpdate(),
42+
history.getLastPageRead()
43+
);
44+
}
45+
46+
return new StudentStatsResponse(
47+
stats.getId(),
48+
userHistory,
49+
stats.getLevel(),
50+
stats.getCurrentExperience(),
51+
stats.getMaxLvlExperience(),
52+
stats.getOngoingStreak(),
53+
stats.getAverageReadingTime(),
54+
stats.getReadingCount()
55+
);
56+
}
57+
2558
@PostMapping("/create/{userId}")
26-
public ResponseEntity<ApiResponse<StudentStats>> createStats(@PathVariable Long userId, HttpServletRequest request) {
59+
public ResponseEntity<ApiResponse<StudentStatsResponse>> createStats(@PathVariable Long userId, HttpServletRequest request) {
2760
StudentStats stats = statsService.create(userId);
28-
ApiResponse<StudentStats> response = ApiResponse.success(stats, "Stats created", request.getRequestURI());
61+
ApiResponse<StudentStatsResponse> response = ApiResponse.success(this.studentStatsToDto(stats), "Stats created", request.getRequestURI());
2962
return ResponseEntity.status(HttpStatus.CREATED).body(response);
3063
}
3164

3265
@GetMapping("/{userId}")
33-
public ResponseEntity<ApiResponse<StudentStats>> getStats(@PathVariable Long userId, HttpServletRequest request) {
66+
public ResponseEntity<ApiResponse<StudentStatsResponse>> getStats(@PathVariable Long userId, HttpServletRequest request) {
67+
// TODO: this is getting a loop in the JSON, fix it
3468
StudentStats stats = statsService.get(userId);
35-
ApiResponse<StudentStats> response = ApiResponse.success(stats, request.getRequestURI());
69+
ApiResponse<StudentStatsResponse> response = ApiResponse.success(this.studentStatsToDto(stats), request.getRequestURI());
3670
return ResponseEntity.ok(response);
3771
}
3872

@@ -47,12 +81,14 @@ public ResponseEntity<ApiResponse<Integer>> calculateAverageReadingTime(
4781
}
4882

4983
@PostMapping("/{statsId}/add-exp")
50-
public ResponseEntity<ApiResponse<StudentStats>> addExperience(
84+
public ResponseEntity<ApiResponse<StudentStatsResponse>> addExperience(
5185
@PathVariable Long statsId,
5286
@Valid @RequestBody AddExperienceRequest request,
5387
HttpServletRequest req
5488
) {
55-
StudentStats stats = statsService.addExp(statsId, request.exp());
89+
StudentStatsResponse stats = this.studentStatsToDto(
90+
statsService.addExp(statsId, request.exp())
91+
);
5692
return ResponseEntity.ok(ApiResponse.success(stats, "Experience added", req.getRequestURI()));
5793
}
5894

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.vianavitor.simplelibrarygame.dto.response;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
import jakarta.annotation.Nullable;
5+
6+
import java.time.LocalDate;
7+
8+
public record BookReadHistoryResponse(
9+
Long id,
10+
StudentInfo user,
11+
UsersBookReadHistoryResponse.BookInfo book,
12+
@JsonProperty("last_update") @Nullable LocalDate lastUpdate,
13+
@JsonProperty("last_page_read") int lastPageRead
14+
) {
15+
public record StudentInfo(
16+
Long id,
17+
String name
18+
) {}
19+
20+
public record BookInfo(
21+
Long id,
22+
String title
23+
) {}
24+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.vianavitor.simplelibrarygame.dto.response;
2+
3+
import jakarta.annotation.Nullable;
4+
5+
public record StudentStatsResponse (
6+
Long id,
7+
@Nullable UsersBookReadHistoryResponse currentBook,
8+
int level,
9+
int currentExperience,
10+
int maxLvlExperience,
11+
int ongoingStreak,
12+
int averageReadingTime,
13+
int readingCount
14+
) {
15+
}

0 commit comments

Comments
 (0)