Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[1 - 3단계 방탈출 사용자 예약] 이든(최승준) 미션 제출합니다. #57

Merged
merged 61 commits into from
May 7, 2024
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
bd5a99e
init: 이전 미션 코드 반영
J-I-H-O Apr 30, 2024
b0bd9bb
style: 줄바꿈 수정
PgmJun Apr 30, 2024
ba6b536
docs: 예외 상황 정의
J-I-H-O Apr 30, 2024
3592c1d
feat: 유효하지 않은 시간 생성 검증 기능 구현
J-I-H-O Apr 30, 2024
75c7ee4
feat: 유효하지 않은 시간 생성 검증 기능 구현
J-I-H-O Apr 30, 2024
ec2e3b0
feat: 예약이 존재하는 시간 삭제를 방어하는 기능 구현
J-I-H-O Apr 30, 2024
e37964d
Merge remote-tracking branch 'origin/step1' into step1
J-I-H-O Apr 30, 2024
a8a4a02
style: 줄바꿈 정리
J-I-H-O Apr 30, 2024
0fe2794
feat: 유효하지 않은 예약 등록 요청 검증 로직 구현
J-I-H-O Apr 30, 2024
540fdee
feat: 중복된 날짜 및 시간 예약 등록 검증 로직 구현
J-I-H-O Apr 30, 2024
5d6008e
chore: gradle 설정 변경
J-I-H-O May 1, 2024
7307152
feat: 지나간 날짜와 시간에 대한 예약 생성 방지 기능 구현
J-I-H-O May 1, 2024
4f592bd
docs: 테마 API 명세 추가
J-I-H-O May 1, 2024
7331554
chore: 테마 관련 DDL 추가
J-I-H-O May 1, 2024
17af3db
feat: 테마 관리 페이지 요청 API 구현
J-I-H-O May 1, 2024
9e8790e
fix: 예약 관리 페이지 파일 변경
J-I-H-O May 1, 2024
e951bbb
docs: 테마 관련 REST API 명세 추가
J-I-H-O May 1, 2024
3bbd400
feat: 테마 조회 기능 구현
J-I-H-O May 1, 2024
40d021b
feat: 테마 추가 기능 구현
J-I-H-O May 1, 2024
ff72e78
feat: 테마 삭제 기능 구현
J-I-H-O May 1, 2024
fe93600
feat: 예약 도메인과 테마 도메인 연동
J-I-H-O May 1, 2024
60d7ed3
feat: 사용자 예약 페이지 요청 API 구현
J-I-H-O May 1, 2024
478963c
chore: 더미 데이터 삽입 SQL 작성
J-I-H-O May 2, 2024
45fbf52
feat: 특정 날짜의 특정 테마 예약 정보 조회 기능 구현
J-I-H-O May 2, 2024
efb21f8
docs: 인기 테마 API 명세 추가
J-I-H-O May 2, 2024
f7177bd
feat: 인기 테마 조회 기능 구현
J-I-H-O May 2, 2024
1f76b8f
refactor: 테스트 성능 개선
J-I-H-O May 2, 2024
772631f
refactor: 메서드 분리
J-I-H-O May 2, 2024
ac95a28
style: 완료된 TODO 제거
J-I-H-O May 2, 2024
830df0c
style: 테스트 given, when, then 분리
J-I-H-O May 2, 2024
cd175dc
style: TODO 제거
J-I-H-O May 2, 2024
2d9aa37
docs: 테마 인기순 조회 API 문서 작성
PgmJun May 2, 2024
23b6a97
refactor: 컨트롤러 공통 Endpoint 매핑 해제
PgmJun May 4, 2024
35935dc
style: 메서드 인자 개행 수정
PgmJun May 4, 2024
5604c83
style: 코드라인 정리
PgmJun May 4, 2024
230ce75
refactor: HTTP Response 형식 수정(List -> Object)
PgmJun May 4, 2024
4cec0d8
style: 컨트롤러 메서드 네이밍 변경
PgmJun May 4, 2024
04131d6
style: DAO 메서드 네이밍 변경
PgmJun May 4, 2024
a0899cf
style: Service 메서드 네이밍 변경
PgmJun May 4, 2024
7b816fd
refactor: 메서드 인자 final로 불변 처리
PgmJun May 4, 2024
4a9a980
refactor: 예약 시간 정보 조회 API Endpoint 수정
PgmJun May 5, 2024
0f8ef2c
refactor: 테스트에서 컴포넌트 객체 사용을 위해 Import 애노테이션 적용
PgmJun May 5, 2024
0470138
refactor: 예외 발생 시 Response도 Object로 처리하도록, 응답 객체 ApiResponse 구현
PgmJun May 5, 2024
c983dfd
test: MVC Controller 테스트 작성
PgmJun May 5, 2024
41fa7a2
feat: 입력부 검증 로직 구현
PgmJun May 5, 2024
818b1eb
feat: 도메인 검증 로직 구현
PgmJun May 5, 2024
a2905fc
refactor: 예약 시간 정보 조회 로직 - 서브 쿼리 사용하여 하나의 SQL로 조회하도록 수정
PgmJun May 5, 2024
79de6f5
refactor: 테스트 코드 `@BeforeEach` 제거하고 필요한 곳에서만 데이터 삽입해주도록 변경
PgmJun May 5, 2024
604a0c0
fix: 00:30분 일때 1시간 전은 23:30분 이기 때문에 다른 날짜로 판별되어 테스트코드 실패하는 문제 해결
PgmJun May 5, 2024
a0f45d0
style: Repository 네이밍 용도에 맞도록 Dao로 변경
PgmJun May 5, 2024
15276bd
refactor: 특정 기간 사이 인기테마 조회 API 쿼리스트링으로 날짜값 받도록 변경
PgmJun May 5, 2024
b40b582
refactor: 의미가 불분명한 ConflictException 네이밍 변경 (DataConflictException)
PgmJun May 6, 2024
7620bc5
refactor: 에러 메시지 클라이언트 친화적으로 개선
PgmJun May 6, 2024
f6b6e37
refactor: Location 헤더 상수 사용하도록 변경
PgmJun May 6, 2024
4014865
refactor: 로깅 예외 메시지 구체화
PgmJun May 7, 2024
80690a0
refactor: 인기테마 조회 API에 defaultValue 적용
PgmJun May 7, 2024
272a414
refactor: 복잡성 제거를 위해 ApiResponse isSuccess 필드 제거
PgmJun May 7, 2024
3175c22
refactor: 예약 시간 정보 조회 쿼리에서 의미없는 조인 쿼리 제거
PgmJun May 7, 2024
81687e0
refactor: 조건식 가독성 향상을 위한 조건문 분리
PgmJun May 7, 2024
bc3aaf6
fix: 잘못된 예외 객체 사용 로직 수정 (DataConflict -> Validate)
PgmJun May 7, 2024
a80fcbd
fix: 불필요한 포맷팅 애노테이션 제거
PgmJun May 7, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 22 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,25 @@

## API 명세

| Method | Endpoint | Description | File Path | Controller Type |
|--------|---------------------------------------|-----------------------|----------------------------------------|-------------------|
| GET | `/` | 인기 테마 페이지 요청 | `templates/index.html` | `@Controller` |
| GET | `/reservation` | 사용자 예약 페이지 요청 | `templates/reservation.html` | `@Controller` |
| GET | `/admin` | 어드민 페이지 요청 | `templates/admin/index.html` | `@Controller` |
| GET | `/admin/reservation` | 예약 관리 페이지 요청 | `templates/admin/reservation-new.html` | `@Controller` |
| GET | `/admin/time` | 예약 시간 관리 페이지 요청 | `templates/admin/time.html` | `@Controller` |
| GET | `/admin/theme` | 테마 관리 페이지 요청 | `templates/admin/theme.html` | `@Controller` |
| GET | `/reservations` | 예약 정보 조회 | | `@RestController` |
| GET | `/reservations/themes/{themeId}?date` | 특정 날짜의 특정 테마 예약 정보 조회 | | `@RestController` |
| POST | `/reservations` | 예약 추가 | | `@RestController` |
| DELETE | `/reservations/{id}` | 예약 취소 | | `@RestController` |
| GET | `/times` | 예약 시간 조회 | | `@RestController` |
| DELETE | `/times/{id}` | 예약 시간 추가 | | `@RestController` |
| POST | `/times` | 예약 시간 삭제 | | `@RestController` |
| GET | `/themes` | 테마 정보 조회 | | `@RestController` |
| GET | `/themes/top?count` | 인기순 테마 조회 | | `@RestController` |
| POST | `/themes` | 테마 추가 | | `@RestController` |
| DELETE | `/themes/{id}` | 테마 삭제 | | `@RestController` |
| Method | Endpoint | Description | File Path | Controller Type |
|--------|---------------------------------------------|-----------------------|----------------------------------------|-------------------|
| GET | `/` | 인기 테마 페이지 요청 | `templates/index.html` | `@Controller` |
| GET | `/reservation` | 사용자 예약 페이지 요청 | `templates/reservation.html` | `@Controller` |
| GET | `/admin` | 어드민 페이지 요청 | `templates/admin/index.html` | `@Controller` |
| GET | `/admin/reservation` | 예약 관리 페이지 요청 | `templates/admin/reservation-new.html` | `@Controller` |
| GET | `/admin/time` | 예약 시간 관리 페이지 요청 | `templates/admin/time.html` | `@Controller` |
| GET | `/admin/theme` | 테마 관리 페이지 요청 | `templates/admin/theme.html` | `@Controller` |
| GET | `/reservations` | 예약 정보 조회 | | `@RestController` |
| GET | `/reservations/themes/{themeId}/times?date` | 특정 날짜의 특정 테마 예약 정보 조회 | | `@RestController` |
| POST | `/reservations` | 예약 추가 | | `@RestController` |
| DELETE | `/reservations/{id}` | 예약 취소 | | `@RestController` |
| GET | `/times` | 예약 시간 조회 | | `@RestController` |
| DELETE | `/times/{id}` | 예약 시간 추가 | | `@RestController` |
| POST | `/times` | 예약 시간 삭제 | | `@RestController` |
| GET | `/themes` | 테마 정보 조회 | | `@RestController` |
| GET | `/themes/top?count&startAt&endAt` | 특정 기간의 인기 테마 조회 | | `@RestController` |
| POST | `/themes` | 테마 추가 | | `@RestController` |
| DELETE | `/themes/{id}` | 테마 삭제 | | `@RestController` |

---

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

꼼꼼한 API 문서네요 ㅎ 👍

Expand Down Expand Up @@ -58,7 +58,7 @@ Content-Type: application/json
- Request

```
GET /reservations/themes/1?date=2024-12-31 HTTP/1.1
GET /reservations/themes/1/times?date=2024-12-31 HTTP/1.1
```

---
Expand Down Expand Up @@ -225,12 +225,12 @@ Content-Type: application/json

---

### 인기순 테마 조회 API
### 특정 기간의 인기 테마 조회 API

- Request

```
GET /themes/top?count=10 HTTP/1.1
GET /themes/top?count=10&startAt=2024-01-01&endAt=2024-01-07 HTTP/1.1
```

- response
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/roomescape/RoomescapeApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
@SpringBootApplication
public class RoomescapeApplication {

public static void main(String[] args) {
public static void main(final String[] args) {
SpringApplication.run(RoomescapeApplication.class, args);
}

Expand Down
18 changes: 8 additions & 10 deletions src/main/java/roomescape/controller/AdminController.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,27 @@

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/admin")
public class AdminController {

@GetMapping
public String readAdminPage() {
@GetMapping("/admin")
public String showAdminPage() {
return "admin/index";
}

@GetMapping("/reservation")
public String readAdminReservationPage() {
@GetMapping("/admin/reservation")
public String showAdminReservationPage() {
return "admin/reservation-new";
}

@GetMapping("/time")
public String readAdminTimePage() {
@GetMapping("/admin/time")
public String showAdminTimePage() {
return "admin/time";
}

@GetMapping("/theme")
public String readAdminThemePage() {
@GetMapping("/admin/theme")
public String showAdminThemePage() {
return "admin/theme";
}
}
4 changes: 2 additions & 2 deletions src/main/java/roomescape/controller/ClientController.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
public class ClientController {

@GetMapping("/")
public String readPopularThemePage() {
public String showPopularThemePage() {
return "index";
}

@GetMapping("/reservation")
public String readReservationPage() {
public String showReservationPage() {
return "reservation";
}
}
62 changes: 33 additions & 29 deletions src/main/java/roomescape/controller/ReservationController.java
Original file line number Diff line number Diff line change
@@ -1,61 +1,65 @@
package roomescape.controller;

import java.net.URI;
import java.time.LocalDate;
import java.util.List;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.ResponseEntity;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import roomescape.dto.reservation.ReservationAvailableTimeResponse;
import roomescape.dto.reservation.ReservationRequest;
import roomescape.dto.reservation.ReservationResponse;
import roomescape.dto.reservation.ReservationTimeInfosResponse;
import roomescape.dto.reservation.ReservationsResponse;
import roomescape.global.dto.response.ApiResponse;
import roomescape.service.ReservationService;

import java.time.LocalDate;

@RestController
@RequestMapping("/reservations")
public class ReservationController {

private final ReservationService reservationService;

public ReservationController(ReservationService reservationService) {
public ReservationController(final ReservationService reservationService) {
this.reservationService = reservationService;
}

@GetMapping
public ResponseEntity<List<ReservationResponse>> readReservations() {
List<ReservationResponse> reservationResponses = reservationService.findAllReservations();

return ResponseEntity.ok(reservationResponses);
@GetMapping("/reservations")
@ResponseStatus(HttpStatus.OK)
public ApiResponse<ReservationsResponse> getAllReservations() {
return ApiResponse.success(reservationService.findAllReservations());
}

@GetMapping("/themes/{themeId}")
public ResponseEntity<List<ReservationAvailableTimeResponse>> readAvailableTimeReservations(
@PathVariable
Long themeId,
@RequestParam
@DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate date) {
return ResponseEntity.ok(reservationService.findReservationByDateAndThemeId(date, themeId));
@GetMapping("/reservations/themes/{themeId}/times")
@ResponseStatus(HttpStatus.OK)
public ApiResponse<ReservationTimeInfosResponse> getReservationTimeInfos(
@PathVariable final Long themeId,
@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") final LocalDate date) {
return ApiResponse.success(reservationService.findReservationsByDateAndThemeId(date, themeId));
}

@PostMapping
public ResponseEntity<ReservationResponse> createReservation(@RequestBody ReservationRequest reservationRequest) {
ReservationResponse reservationResponse = reservationService.createReservation(reservationRequest);
@PostMapping("/reservations")
@ResponseStatus(HttpStatus.CREATED)
public ApiResponse<ReservationResponse> saveReservation(
@RequestBody final ReservationRequest reservationRequest,
HttpServletResponse response
) {
ReservationResponse reservationResponse = reservationService.addReservation(reservationRequest);

return ResponseEntity.created(URI.create("/reservations/" + reservationResponse.id()))
.body(reservationResponse);
response.setHeader("Location", "/reservations/" + reservationResponse.id());

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Location이라는 변수명이 실수할 여지가 있어서 수정 전 방식대로 활용하시는 것도 좋다고 생각합니다 ㅎ

이런 방법도 있습니다.

    @PostMapping("/reservations")
    public ResponseEntity<ApiResponse<ReservationResponse>> saveReservation(
            @RequestBody final ReservationRequest reservationRequest
    ) {
        ReservationResponse reservationResponse = reservationService.addReservation(reservationRequest);

        URI location = ServletUriComponentsBuilder.fromCurrentRequest()
                .path("/{id}")
                .buildAndExpand(reservationResponse.id())
                .toUri();

        return ResponseEntity.created(location).body(ApiResponse.success(reservationResponse));
    }

Copy link
Author

@PgmJun PgmJun May 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

지금처럼 일반 문자열로 관리하면 충분히 실수할 여지가 있을 것 같습니다..!
예시로 첨부해주신 내용도 너무 좋은 것 같습니다!

그런데 로직이 너무 길어지는 느낌이 있어서
혹시 Location이라는 문자열을 실수할 여지가 있는 부분에 대해
미리 정의되어있는 HttpHeaders.LOCATION 을 활용해서 해결하는 방식은 어떤가요??

response.setHeader(HttpHeaders.LOCATION, "/reservations/" + reservationResponse.id());

이렇게 변경해볼 수 있을 것 같습니다!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

네네 우려하는 부분은 매직넘버이니 좋은 처리입니다 ㅎ

return ApiResponse.success(reservationResponse);
}

@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteReservation(@PathVariable Long id) {
reservationService.deleteReservation(id);
@DeleteMapping("/reservations/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public ApiResponse<Void> removeReservation(@PathVariable final Long id) {
reservationService.removeReservationById(id);

return ResponseEntity.noContent().build();
return ApiResponse.success();
}
}
59 changes: 35 additions & 24 deletions src/main/java/roomescape/controller/ThemeController.java
Original file line number Diff line number Diff line change
@@ -1,56 +1,67 @@
package roomescape.controller;

import java.net.URI;
import java.util.List;
import org.springframework.http.ResponseEntity;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import roomescape.dto.theme.ThemeRequest;
import roomescape.dto.theme.ThemeResponse;
import roomescape.dto.theme.ThemesResponse;
import roomescape.global.dto.response.ApiResponse;
import roomescape.service.ThemeService;

import java.time.LocalDate;

@RestController
@RequestMapping("/themes")
public class ThemeController {

private final ThemeService themeService;

public ThemeController(ThemeService themeService) {
public ThemeController(final ThemeService themeService) {
this.themeService = themeService;
}

@GetMapping
public ResponseEntity<List<ThemeResponse>> readThemes() {
List<ThemeResponse> themeResponses = themeService.findAllThemes();
@GetMapping("/themes")
@ResponseStatus(HttpStatus.OK)
public ApiResponse<ThemesResponse> getAllThemes() {

return ResponseEntity.ok(themeResponses);
return ApiResponse.success(themeService.findAllThemes());
}

@GetMapping("/top")
public ResponseEntity<List<ThemeResponse>> readTopNThemes(@RequestParam int count) {
List<ThemeResponse> themeResponses = themeService.findTopNThemes(count);

return ResponseEntity.ok(themeResponses);
@GetMapping("/themes/top")
@ResponseStatus(HttpStatus.OK)
public ApiResponse<ThemesResponse> getTopNThemesBetweenDate(
@RequestParam final int count,
@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") final LocalDate startAt,
@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") final LocalDate endAt
) {
return ApiResponse.success(themeService.findTopNThemes(count, startAt, endAt));
}

@PostMapping
public ResponseEntity<ThemeResponse> createTheme(@RequestBody ThemeRequest request) {
ThemeResponse response = themeService.createTheme(request);
@PostMapping("/themes")
@ResponseStatus(HttpStatus.CREATED)
public ApiResponse<ThemeResponse> saveTheme(
@RequestBody final ThemeRequest request,
HttpServletResponse response
) {
ThemeResponse themeResponse = themeService.addTheme(request);
response.setHeader("Location", "/themes/" + themeResponse.id());

return ResponseEntity.created(URI.create("/themes/" + response.id()))
.body(response);
return ApiResponse.success(themeResponse);
}

@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteTheme(@PathVariable Long id) {
themeService.deleteTheme(id);
@DeleteMapping("/themes/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public ApiResponse<Void> removeTheme(@PathVariable final Long id) {
themeService.removeThemeById(id);

return ResponseEntity.noContent().build();
return ApiResponse.success();
}
}
43 changes: 24 additions & 19 deletions src/main/java/roomescape/controller/TimeController.java
Original file line number Diff line number Diff line change
@@ -1,48 +1,53 @@
package roomescape.controller;

import java.net.URI;
import java.util.List;
import org.springframework.http.ResponseEntity;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import roomescape.dto.time.TimeRequest;
import roomescape.dto.time.TimeResponse;
import roomescape.dto.time.TimesResponse;
import roomescape.global.dto.response.ApiResponse;
import roomescape.service.TimeService;

@RestController
@RequestMapping("/times")
public class TimeController {

private final TimeService timeService;

public TimeController(TimeService timeService) {
public TimeController(final TimeService timeService) {
this.timeService = timeService;
}

@GetMapping
public ResponseEntity<List<TimeResponse>> readTimes() {
List<TimeResponse> timeResponses = timeService.findAllTimes();
@GetMapping("/times")
@ResponseStatus(HttpStatus.OK)
public ApiResponse<TimesResponse> getAllTimes() {

return ResponseEntity.ok(timeResponses);
return ApiResponse.success(timeService.findAllTimes());
}

@PostMapping
public ResponseEntity<TimeResponse> createTime(@RequestBody TimeRequest timeRequest) {
TimeResponse timeResponse = timeService.createTime(timeRequest);
@PostMapping("/times")
@ResponseStatus(HttpStatus.CREATED)
public ApiResponse<TimeResponse> saveTime(
@RequestBody final TimeRequest timeRequest,
HttpServletResponse response
) {
TimeResponse timeResponse = timeService.addTime(timeRequest);
response.setHeader("Location", "/times/" + timeResponse.id());

return ResponseEntity.created(URI.create("/times/" + timeResponse.id()))
.body(timeResponse);
return ApiResponse.success(timeResponse);
}

@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteTime(@PathVariable Long id) {
timeService.deleteTime(id);
@DeleteMapping("/times/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public ApiResponse<Void> removeTime(@PathVariable final Long id) {
timeService.removeTimeById(id);

return ResponseEntity.noContent().build();
return ApiResponse.success();
}
}
Loading