Skip to content

[feat] API & Swagger & Annotationย #9

@millkk04

Description

@millkk04

๐Ÿ“Œ ์ž‘์—… ๊ฐœ์š”

REST API 3๊ฐœ๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ , Custom Validation ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.


โœ… ์™„๋ฃŒ๋œ ์ž‘์—…

1. ๋ฆฌ๋ทฐ ์ถ”๊ฐ€ API ๊ตฌํ˜„

  • Endpoint: POST /api/reviews?memberId={memberId}
  • ๊ธฐ๋Šฅ: ๊ฐ€๊ฒŒ์— ๋ฆฌ๋ทฐ ์ž‘์„ฑ
  • Request Body: storeId, star (0.05.0), content (101000์ž)
  • ๊ตฌํ˜„ ํŒŒ์ผ:
    • ReviewController, ReviewConverter
    • ReviewReqDTO, ReviewResDTO
    • ReviewErrorCode, ReviewException
    • ReviewCommandService, ReviewCommandServiceImpl
    • StoreRepository (์‹ ๊ทœ ์ƒ์„ฑ)

2. ๋ฏธ์…˜ ๋„์ „ API ๊ตฌํ˜„

  • Endpoint: POST /api/members/{memberId}/missions/{missionId}
  • ๊ธฐ๋Šฅ: ํšŒ์›์ด ํŠน์ • ๋ฏธ์…˜์— ๋„์ „
  • ์ฃผ์š” ๊ฒ€์ฆ: ๋ฏธ์…˜ ๋งˆ๊ฐ์ผ, ์ค‘๋ณต ๋„์ „, ๊ฐ€๊ฒŒ/ํšŒ์› ์กด์žฌ ์—ฌ๋ถ€
  • ๊ตฌํ˜„ ํŒŒ์ผ:
    • MissionController, MissionConverter
    • MissionReqDTO, MissionResDTO
    • MissionErrorCode, MissionException
    • MissionRepository, MemberMissionRepository (์ค‘๋ณต ์ฒดํฌ ๋ฉ”์„œ๋“œ ์ถ”๊ฐ€)
    • MissionCommandService, MissionCommandServiceImpl

3. ๊ฐ€๊ฒŒ ์ถ”๊ฐ€ API ๊ตฌํ˜„

  • Endpoint: POST /api/stores
  • ๊ธฐ๋Šฅ: ์ƒˆ๋กœ์šด ๊ฐ€๊ฒŒ ๋“ฑ๋ก
  • Request Body: name, managerNumber, detailAddress, locationId
  • ๊ตฌํ˜„ ํŒŒ์ผ:
    • StoreController, StoreConverter
    • StoreReqDTO, StoreResDTO
    • StoreErrorCode, StoreException
    • LocationRepository (์‹ ๊ทœ ์ƒ์„ฑ)
    • StoreCommandService, StoreCommandServiceImpl

4. ๊ฐ€๊ฒŒ์— ๋ฏธ์…˜ ์ถ”๊ฐ€ API ๊ตฌํ˜„

  • Endpoint: POST /api/stores/{storeId}/missions
  • ๊ธฐ๋Šฅ: ํŠน์ • ๊ฐ€๊ฒŒ์— ๋ฏธ์…˜ ์ƒ์„ฑ
  • Request Body: deadline, conditional, point
  • ๊ตฌํ˜„ ํŒŒ์ผ:
    • MissionController (๋ฉ”์„œ๋“œ ์ถ”๊ฐ€)
    • MissionConverter (๋ณ€ํ™˜ ๋ฉ”์„œ๋“œ ์ถ”๊ฐ€)
    • MissionReqDTO, MissionResDTO (DTO ์ถ”๊ฐ€)
    • MissionCommandService, MissionCommandServiceImpl (๋กœ์ง ์ถ”๊ฐ€)

5. Custom Validation ๊ธฐ๋Šฅ ๊ตฌํ˜„

  • @ExistFoods: ์Œ์‹ ์นดํ…Œ๊ณ ๋ฆฌ ์กด์žฌ ์—ฌ๋ถ€ ๊ฒ€์ฆ

    • FoodExistValidator ๊ตฌํ˜„
    • FoodRepository.existsById() ํ™œ์šฉ
  • @UniqueEmail: ์ด๋ฉ”์ผ ์ค‘๋ณต ๊ฒ€์ฆ

    • UniqueEmailValidator ๊ตฌํ˜„
    • MemberRepository.existsByEmail() ํ™œ์šฉ
  • GlobalExceptionHandler ํ™•์žฅ:

    • MethodArgumentNotValidException ์ฒ˜๋ฆฌ ์ถ”๊ฐ€
    • Validation ์‹คํŒจ ์‹œ ํ•„๋“œ๋ณ„ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ๋ฐ˜ํ™˜

6. ํšŒ์›๊ฐ€์ž… API ๊ฐœ์„ 

  • URL ๋ณ€๊ฒฝ: POST /api/members/register โ†’ POST /api/auth/register
  • Validation ์ ์šฉ: @ExistFoods, @UniqueEmail, @Valid
  • ์—๋Ÿฌ ์ฒ˜๋ฆฌ ๊ฐœ์„ :
    • "์˜ˆ๊ธฐ์น˜ ์•Š์€ ์„œ๋ฒ„ ์—๋Ÿฌ" โ†’ "์ด๋ฏธ ๊ฐ€์ž…ํ•œ ์ด๋ฉ”์ผ์ž…๋‹ˆ๋‹ค"
    • Validation ์‹คํŒจ ์‹œ ๊ตฌ์ฒด์ ์ธ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ๋ฐ˜ํ™˜

๐Ÿ—‚๏ธ ์ƒ์„ฑ/์ˆ˜์ •๋œ ์ฃผ์š” ํŒŒ์ผ

์‹ ๊ทœ ์ƒ์„ฑ

  • StoreRepository.java
  • LocationRepository.java
  • global/annotation/ExistFoods.java
  • global/annotation/UniqueEmail.java
  • global/validator/FoodExistValidator.java
  • global/validator/UniqueEmailValidator.java

์ˆ˜์ •

  • ReviewController, ReviewConverter, ReviewReqDTO, ReviewResDTO, ReviewErrorCode, ReviewException, ReviewCommandService, ReviewCommandServiceImpl
  • MissionController, MissionConverter, MissionReqDTO, MissionResDTO, MissionErrorCode, MissionException, MissionCommandService, MissionCommandServiceImpl
  • StoreController, StoreConverter, StoreReqDTO, StoreResDTO, StoreErrorCode, StoreException, StoreCommandService, StoreCommandServiceImpl
  • MemberReqDTO (Validation ์ถ”๊ฐ€)
  • MemberController (URL ๋ณ€๊ฒฝ)
  • GlobalExceptionHandler (Validation ์—๋Ÿฌ ์ฒ˜๋ฆฌ ์ถ”๊ฐ€)

๐ŸŽฏ API ์—”๋“œํฌ์ธํŠธ ๋ชฉ๋ก

Method Endpoint ๊ธฐ๋Šฅ
POST /api/auth/register ํšŒ์›๊ฐ€์ž…
POST /api/reviews ๋ฆฌ๋ทฐ ์ž‘์„ฑ
POST /api/members/{memberId}/missions/{missionId} ๋ฏธ์…˜ ๋„์ „
POST /api/stores ๊ฐ€๊ฒŒ ์ถ”๊ฐ€
POST /api/stores/{storeId}/missions ๋ฏธ์…˜ ์ถ”๊ฐ€

๐Ÿ“ ๊ธฐ์ˆ  ์Šคํƒ

  • Spring Boot 3.5.7
  • Java 21
  • JPA / Hibernate
  • MySQL
  • Bean Validation
  • QueryDSL
  • Springdoc OpenAPI (Swagger)

๐Ÿ” ์ฃผ์š” ์ ์šฉ ๊ธฐ์ˆ 

1. Validation

  • @Valid, @NotNull, @NotBlank, @Size, @Min, @Max
  • @Email, @Past, @Future, @DecimalMin, @DecimalMax
  • Custom Validator: @ExistFoods, @UniqueEmail

2. ์˜ˆ์™ธ ์ฒ˜๋ฆฌ

  • Custom Exception: ReviewException, MissionException, StoreException
  • ErrorCode Enum: ReviewErrorCode, MissionErrorCode, StoreErrorCode
  • GlobalExceptionHandler๋กœ ์ผ๊ด€๋œ ์—๋Ÿฌ ์‘๋‹ต ํ˜•์‹

3. RESTful API ์„ค๊ณ„

  • ๋ฆฌ์†Œ์Šค ๊ณ„์ธต ๊ตฌ์กฐ ๋ช…ํ™•ํ™”
  • HTTP ๋ฉ”์„œ๋“œ์™€ ์ƒํƒœ ์ฝ”๋“œ ์ ์ ˆํžˆ ์‚ฌ์šฉ (201 Created, 404 Not Found ๋“ฑ)
  • PathVariable๊ณผ RequestBody ์ ์ ˆํžˆ ๋ถ„๋ฆฌ

4. ํŠธ๋žœ์žญ์…˜ ๊ด€๋ฆฌ

  • @Transactional ์ ์šฉ
  • ์˜ˆ์™ธ ๋ฐœ์ƒ ์‹œ ์ž๋™ ๋กค๋ฐฑ

๐Ÿ› ํ•ด๊ฒฐํ•œ ์ด์Šˆ

1. ํšŒ์›๊ฐ€์ž… ์‹œ email null ์—๋Ÿฌ

  • ์›์ธ: Member ์—”ํ‹ฐํ‹ฐ์˜ email ํ•„๋“œ๊ฐ€ nullable=false์ธ๋ฐ ์š”์ฒญ์— email์ด ์—†์Œ
  • ํ•ด๊ฒฐ: MemberReqDTO์— email ํ•„๋“œ ์ถ”๊ฐ€, @Email ๋ฐ @UniqueEmail validation ์ ์šฉ

2. ์Œ์‹ ์นดํ…Œ๊ณ ๋ฆฌ ์กด์žฌํ•˜์ง€ ์•Š์Œ ์—๋Ÿฌ

  • ์›์ธ: DB์— food_category ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์Œ
  • ํ•ด๊ฒฐ: INSERT๋ฌธ ์ž‘์„ฑ ๋ฐ data.sql์— ์ถ”๊ฐ€

3. ์ด๋ฉ”์ผ ์ค‘๋ณต ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ์ง€์ €๋ถ„ํ•จ

  • ์›์ธ: DB constraint ์œ„๋ฐ˜ ์‹œ SQL ์˜ˆ์™ธ ๋ฉ”์‹œ์ง€๊ฐ€ ๊ทธ๋Œ€๋กœ ๋…ธ์ถœ
  • ํ•ด๊ฒฐ: @UniqueEmail custom validator๋กœ ์‚ฌ์ „ ๊ฒ€์ฆ

4. Validation ์‹คํŒจ ์‹œ ์—๋Ÿฌ ์‘๋‹ต ํ˜•์‹ ๋ถˆ์ผ์น˜

  • ์›์ธ: MethodArgumentNotValidException ๋ฏธ์ฒ˜๋ฆฌ
  • ํ•ด๊ฒฐ: GlobalExceptionHandler์— ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ์ถ”๊ฐ€

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions