Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 8
feat: region 관련 관리 기능 추가#561
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
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| package com.example.solidconnection.admin.location.region.controller; | ||
| import com.example.solidconnection.admin.location.region.dto.AdminRegionCreateRequest; | ||
| import com.example.solidconnection.admin.location.region.dto.AdminRegionResponse; | ||
| import com.example.solidconnection.admin.location.region.dto.AdminRegionUpdateRequest; | ||
| import com.example.solidconnection.admin.location.region.service.AdminRegionService; | ||
| import jakarta.validation.Valid; | ||
| import java.util.List; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.http.HttpStatus; | ||
| import org.springframework.http.ResponseEntity; | ||
| 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.PutMapping; | ||
| import org.springframework.web.bind.annotation.RequestBody; | ||
| import org.springframework.web.bind.annotation.RequestMapping; | ||
| import org.springframework.web.bind.annotation.RestController; | ||
| @RequiredArgsConstructor | ||
| @RequestMapping("/admin/regions") | ||
| @RestController | ||
| public class AdminRegionController { | ||
| private final AdminRegionService adminRegionService; | ||
| @GetMapping | ||
| public ResponseEntity<List<AdminRegionResponse>> getAllRegions() { | ||
| List<AdminRegionResponse> responses = adminRegionService.getAllRegions(); | ||
| return ResponseEntity.ok(responses); | ||
| } | ||
| @PostMapping | ||
| public ResponseEntity<AdminRegionResponse> createRegion( | ||
| @Valid @RequestBody AdminRegionCreateRequest request | ||
| ) { | ||
| AdminRegionResponse response = adminRegionService.createRegion(request); | ||
| return ResponseEntity.status(HttpStatus.CREATED).body(response); | ||
| } | ||
| @PutMapping("/{code}") | ||
| public ResponseEntity<AdminRegionResponse> updateRegion( | ||
| @PathVariable String code, | ||
| @Valid @RequestBody AdminRegionUpdateRequest request | ||
| ) { | ||
| AdminRegionResponse response = adminRegionService.updateRegion(code, request); | ||
| return ResponseEntity.ok(response); | ||
| } | ||
| @DeleteMapping("/{code}") | ||
| public ResponseEntity<Void> deleteRegion( | ||
| @PathVariable String code | ||
| ) { | ||
| adminRegionService.deleteRegion(code); | ||
| return ResponseEntity.noContent().build(); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| package com.example.solidconnection.admin.location.region.dto; | ||
| import jakarta.validation.constraints.NotBlank; | ||
| import jakarta.validation.constraints.Size; | ||
| public record AdminRegionCreateRequest( | ||
| @NotBlank(message = "지역 코드는 필수입니다") | ||
| @Size(min = 1, max = 10, message = "지역 코드는 1자 이상 10자 이하여야 합니다") | ||
| String code, | ||
| @NotBlank(message = "한글 지역명은 필수입니다") | ||
| @Size(min = 1, max = 100, message = "한글 지역명은 1자 이상 100자 이하여야 합니다") | ||
| String koreanName | ||
| ) { | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| package com.example.solidconnection.admin.location.region.dto; | ||
| import com.example.solidconnection.location.region.domain.Region; | ||
| public record AdminRegionResponse( | ||
| String code, | ||
| String koreanName | ||
| ) { | ||
| public static AdminRegionResponse from(Region region) { | ||
| return new AdminRegionResponse( | ||
| region.getCode(), | ||
| region.getKoreanName() | ||
| ); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| package com.example.solidconnection.admin.location.region.dto; | ||
| import jakarta.validation.constraints.NotBlank; | ||
| import jakarta.validation.constraints.Size; | ||
| public record AdminRegionUpdateRequest( | ||
| @NotBlank(message = "한글 지역명은 필수입니다") | ||
| @Size(min = 1, max = 100, message = "한글 지역명은 1자 이상 100자 이하여야 합니다") | ||
| String koreanName | ||
| ) { | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| package com.example.solidconnection.admin.location.region.service; | ||
| import com.example.solidconnection.admin.location.region.dto.AdminRegionCreateRequest; | ||
| import com.example.solidconnection.admin.location.region.dto.AdminRegionResponse; | ||
| import com.example.solidconnection.admin.location.region.dto.AdminRegionUpdateRequest; | ||
| import com.example.solidconnection.common.exception.CustomException; | ||
| import com.example.solidconnection.common.exception.ErrorCode; | ||
| import com.example.solidconnection.location.region.domain.Region; | ||
| import com.example.solidconnection.location.region.repository.RegionRepository; | ||
| import java.util.List; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.stereotype.Service; | ||
| import org.springframework.transaction.annotation.Transactional; | ||
| @Service | ||
| @RequiredArgsConstructor | ||
| public class AdminRegionService { | ||
| private final RegionRepository regionRepository; | ||
| @Transactional(readOnly = true) | ||
| public List<AdminRegionResponse> getAllRegions() { | ||
| return regionRepository.findAll() | ||
| .stream() | ||
| .map(AdminRegionResponse::from) | ||
| .toList(); | ||
| } | ||
| @Transactional | ||
| public AdminRegionResponse createRegion(AdminRegionCreateRequest request) { | ||
| validateCodeNotExists(request.code()); | ||
| validateKoreanNameNotExists(request.koreanName()); | ||
| Region region = new Region(request.code(), request.koreanName()); | ||
| Region savedRegion = regionRepository.save(region); | ||
| return AdminRegionResponse.from(savedRegion); | ||
| } | ||
| private void validateCodeNotExists(String code) { | ||
| regionRepository.findById(code) | ||
| .ifPresent(region -> { | ||
| throw new CustomException(ErrorCode.REGION_ALREADY_EXISTS); | ||
| }); | ||
| } | ||
| private void validateKoreanNameNotExists(String koreanName) { | ||
| regionRepository.findByKoreanName(koreanName) | ||
| .ifPresent(region -> { | ||
| throw new CustomException(ErrorCode.REGION_ALREADY_EXISTS); | ||
| }); | ||
Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 저희는 | ||
| } | ||
| @Transactional | ||
| public AdminRegionResponse updateRegion(String code, AdminRegionUpdateRequest request) { | ||
| Region region = regionRepository.findById(code) | ||
| .orElseThrow(() -> new CustomException(ErrorCode.REGION_NOT_FOUND)); | ||
| validateKoreanNameNotDuplicated(request.koreanName(), code); | ||
| region.updateKoreanName(request.koreanName()); | ||
| return AdminRegionResponse.from(region); | ||
| } | ||
| private void validateKoreanNameNotDuplicated(String koreanName, String excludeCode) { | ||
| regionRepository.findByKoreanName(koreanName) | ||
| .ifPresent(existingRegion -> { | ||
| if (!existingRegion.getCode().equals(excludeCode)) { | ||
| throw new CustomException(ErrorCode.REGION_ALREADY_EXISTS); | ||
| } | ||
| }); | ||
| } | ||
| @Transactional | ||
| public void deleteRegion(String code) { | ||
| Region region = regionRepository.findById(code) | ||
| .orElseThrow(() -> new CustomException(ErrorCode.REGION_NOT_FOUND)); | ||
| regionRepository.delete(region); | ||
| } | ||
Gyuhyeok99 marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
응답 코드를 지정하는 방향으로 작성해주었네요
여담으로 예전에 RESTful API 설계 원칙에 맞게 응답 코드를 지정하자고 얘기가 나왔던 것으로 기억하는데, 여유 생기면 한 번 진행해봐야겠네요