Skip to content

[정다운] sprint5#87

Open
nocturne9095 wants to merge 3 commits into
codeit-bootcamp-spring:정다운from
nocturne9095:정다운-sprint5

Hidden character warning

The head ref may contain hidden characters: "\uc815\ub2e4\uc6b4-sprint5"
Open

[정다운] sprint5#87
nocturne9095 wants to merge 3 commits into
codeit-bootcamp-spring:정다운from
nocturne9095:정다운-sprint5

Conversation

@nocturne9095
Copy link
Copy Markdown
Collaborator

@nocturne9095 nocturne9095 commented May 3, 2026

요구사항

기본

  • 스프린트 미션#4에서 구현한 API를 RESTful API로 다시 설계해보세요.
  • Postman을 활용해 컨트롤러를 테스트 하세요.
    Postman API 테스트 결과를 export하여 PR에 첨부해주세요.
  • springdoc-openapi를 활용하여 Swagger 기반의 API 문서를 생성하세요.
  • Swagger-UI를 활용해 API를 테스트해보세요.

심화

  • 다음의 정적 리소스를 서빙하여 프론트엔드와 통합해보세요. API 스펙을 준수했다면 잘 동작할거예요.
  • Railway.app을 활용하여 애플리케이션을 배포해보세요.
    Railway.app은 애플리케이션을 쉽게 배포할 수 있도록 도와주는 PaaS입니다.
    [ ] Railway.app에 가입하고, 배포할 GitHub 레포지토리를 연결하세요.
    [ ] Settings > Network 섹션에서 Generate Domain 버튼을 통해 도메인을 생성하세요.
    [ ] 생성된 도메인에 접속해 배포된 애플리케이션을 테스트해보세요.

주요 변경사항

Mission_5.postman_collection.json

스크린샷

-Postman 결과 일부
image
image

-Swagger-UI 활용 결과 일부
image
image
image

-심화 요구사항 : 화면 가이드
image
image
image

멘토에게

  • 심화 요구사항에서 배포는 하지 못했습니다. 추후 진행해보도록 하겠습니다.

@nocturne9095 nocturne9095 requested a review from hagyutae May 3, 2026 15:04
Copy link
Copy Markdown
Collaborator

@hagyutae hagyutae left a comment

Choose a reason for hiding this comment

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

리뷰 요약

중요

  • 현재 스프린트 미션 마다 구현을 mission_# 방식으로 추가하고 있습니다. 이렇게 미션 마다 새로 구현을 추가하는 것이 아니라, src/ 하위에 내용을 수정해가면서 진행해야합니다. 팀 내 다른 사람들 진행 방식 참고하셔서 다음 스프린트 미션 때 꼭 적용해주세요.

요구사항 충족 여부

  • RESTful API 재설계: 전체적인 REST 구조(리소스 기반 URL, HTTP 메서드 활용, 상태 코드 반환)는 잘 구현되어 있으나, API 스펙과 비교했을 때 HTTP 메서드(PUT vs PATCH), 엔드포인트 경로, 쿼리 파라미터 이름 등에서 불일치가 다수 존재합니다.
  • Postman 테스트: PR에 Postman collection JSON이 첨부되어 있어 충족됩니다.
  • springdoc-openapi / Swagger: build.gradlespringdoc-openapi-starter-webmvc-ui 의존성이 추가되어 Swagger UI 자동 생성은 가능하나, 컨트롤러에 @Operation, @ApiResponse, @Tag 등의 Swagger 어노테이션이 전혀 없어 API 문서의 품질이 낮습니다.
  • 프론트엔드 통합(심화): 정적 리소스 파일이 포함되어 있어 충족됩니다.
  • Railway 배포(심화): 미구현 (PR 설명에 명시됨).

주요 문제점

  1. API 스펙 불일치가 다수 — 수정/업데이트 엔드포인트에서 PUT 대신 PATCH를 사용해야 하고, 경로명과 쿼리 파라미터명이 스펙과 다릅니다. 프론트엔드 연동 시 문제가 됩니다.
  2. 보안 이슈 — User 엔티티를 그대로 응답하여 password가 JSON에 노출됩니다.
  3. 빌드 아티팩트/IDE 설정 파일 커밋.gradle/, build/, .idea/, .discodeit/*.ser 파일들이 커밋되어 있어 저장소가 불필요하게 비대해집니다.
  4. Swagger 어노테이션 부재 — springdoc 의존성만 추가하고 실제 API 문서화 어노테이션이 없습니다.

.body(createdUser);
}

@PutMapping(value = "/{userId}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

API 스펙에서 User 수정은 PATCH /api/users/{userId}로 정의되어 있지만, 여기서는 @PutMapping을 사용하고 있습니다. PUT은 리소스 전체를 교체하는 의미이고, PATCH는 부분 수정입니다. UserUpdateRequestnewUsername, newEmail, newPassword 등 선택적 필드를 사용하므로 의미상으로도 PATCH가 맞습니다.

@PatchMapping(value = "/{userId}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)

같은 이유로 UserStatus 업데이트(76번 줄)도 @PatchMapping으로 변경해야 합니다.

return ResponseEntity.ok(userService.findAll());
}

@PutMapping(value = "/{userId}/status")
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

API 스펙에서는 UserStatus 업데이트 경로가 /api/users/{userId}/userStatus이지만, 현재 구현은 /{userId}/status로 되어 있습니다. 프론트엔드 연동 시 경로 불일치로 동작하지 않을 수 있습니다.

@PatchMapping(value = "/{userId}/userStatus")

로 수정하세요.

import java.util.UUID;

@Getter
public class User implements Serializable {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

보안 이슈: User 엔티티가 password 필드를 포함한 채로 API 응답에 그대로 직렬화됩니다. AuthController.login(), UserController.create(), UserController.update() 모두 User 객체를 반환하므로 비밀번호가 JSON 응답에 노출됩니다.

최소한 password 필드에 @JsonIgnore를 추가하거나, 응답 전용 DTO를 사용하는 것이 좋습니다.

@JsonIgnore
private String password;

}

@GetMapping
public ResponseEntity<List<BinaryContent>> findAllByIdIn(
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

API 스펙에서 여러 BinaryContent 조회 시 쿼리 파라미터 이름이 binaryContentIds이지만, 현재 구현은 ids로 되어 있습니다. 프론트엔드와 스펙 준수를 위해 파라미터 이름을 맞춰야 합니다.

@GetMapping
public ResponseEntity<List<BinaryContent>> findAllByIdIn(
    @RequestParam("binaryContentIds") List<UUID> binaryContentIds) {

.body(createdMessage);
}

@PutMapping("/{messageId}")
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

API 스펙에서 Message 수정은 PATCH /api/messages/{messageId}로 정의되어 있습니다. 현재 @PutMapping으로 되어 있으므로 @PatchMapping으로 변경해야 합니다. 이미 PatchMapping import가 있는 것으로 보아 인지는 하고 계신 것 같은데, 실제 적용이 안 되어 있습니다.

ReadStatusController(37번 줄)와 ChannelController(49번 줄)의 update 메서드도 동일하게 @PatchMapping으로 변경이 필요합니다.

import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

@RequiredArgsConstructor
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[전체] springdoc-openapi 의존성은 추가되어 있지만, 컨트롤러에 @Tag, @Operation, @ApiResponse 등의 Swagger 어노테이션이 전혀 없습니다. 기본 자동 생성 문서만으로는 API 문서의 품질이 낮습니다. 최소한 각 컨트롤러에 @Tag를, 각 엔드포인트에 @Operation(summary = "...")을 추가하여 API 문서를 보강하세요.

@Tag(name = "User", description = "User API")
@RestController
@RequestMapping("/api/users")
public class UserController {

  @Operation(summary = "User 등록")
  @ApiResponse(responseCode = "201", description = "User가 성공적으로 생성됨")
  @PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
  public ResponseEntity<User> create(...) { ... }
}

@@ -0,0 +1,10 @@
# Default ignored files
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[전체] mission_4/ 디렉토리에 .gradle/, build/ (컴파일된 .class 파일), .idea/, .discodeit/*.ser (직렬화된 데이터 파일) 등 버전 관리에 포함되면 안 되는 파일들이 대량으로 커밋되어 있습니다. 이들은 .gitignore에 추가하고 Git 추적에서 제거해야 합니다.

특히 .ser 파일은 테스트 중 생성된 로컬 데이터이고, build/ 디렉토리는 빌드 아티팩트이며, .idea/는 IDE 설정 파일입니다. 저장소 용량을 불필요하게 차지하고 다른 개발자 환경과 충돌할 수 있습니다.

);
return Optional.of(binaryContentCreateRequest);
} catch (IOException e) {
throw new RuntimeException(e);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

resolveProfileRequest 메서드에서 IOException 발생 시 RuntimeException으로 감싸서 던지고 있습니다. 이 경우 GlobalExceptionHandlerException 핸들러에 걸려 500 에러가 반환됩니다. 파일 업로드 실패는 클라이언트 입력 문제일 수 있으므로, 좀 더 구체적인 예외(예: IllegalArgumentException)로 변환하거나 적절한 에러 메시지를 포함하는 것이 좋습니다.

MessageController의 84번 줄에도 동일한 패턴이 있습니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants