๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Web Develop/Spring

[Rest API] ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ํ†ตํ•œ ๊ฒŒ์‹œํŒ ๊ธฐ๋Šฅ ๊ตฌํ˜„ํ•˜๊ธฐ_SpringBoot

by tripleup 2023. 10. 25.
728x90
๋ฐ˜์‘ํ˜•

๐Ÿ’ก PURPOSE

๊ฐœ์ธ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๋ ค๊ณ  ํ–ˆ์œผ๋‚˜ ์Šค์Šค๋กœ ์ƒ๊ฐํ•˜๊ธฐ์— ์•„์ง api ์ž‘์„ฑ์— ๋Œ€ํ•ด ๋งŽ์ด ๋ถ€์กฑํ•œ ๊ฒƒ ๊ฐ™์•„ ์–ด๋””์„œ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด์•ผํ•  ์ง€ ๋ชจ๋ฅด๊ฒ ์–ด์„œ ์ผ๋‹จ jpa์— ๋Œ€ํ•œ ๊ธฐ์ดˆ์ ์ธ ์ง€์‹์„ ์Œ“๊ธฐ ์œ„ํ•ด ๊ณต๋ถ€ํ•œ ๊ฒƒ์„ ๋ณต์Šตํ•  ๊ฒธ ํฌ์ŠคํŒ…ํ•ด๋ณด๊ฒ ๋‹ค.


๐Ÿ’ก STUDY LIST

# Subject  1 : ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ํ†ตํ•œ ๊ฒŒ์‹œํŒ ๊ธฐ๋Šฅ ๊ตฌํ˜„ํ•˜๊ธฐ

1. ์ฃผ์†Œ์š”์ฒญ์— ๋Œ€ํ•œ ์ดํ•ด
2. ๊ฒŒ์‹œํŒ ๊ธฐ๋ณธ ๋ชฉ๋ก (6~10)
3. ๊ฒŒ์‹œ๊ธ€ ์ž‘์„ฑ (11~15)
4.๊ฒŒ์‹œ๊ธ€ ์ˆ˜์ •  (16~20)
5.๊ฒŒ์‹œ๊ธ€ ์‚ญ์ œ  (21~25)
6.๊ฒŒ์‹œํŒ ์ถ”๊ฐ€๊ธฐ๋Šฅ  (26~30)


๐Ÿ’ก CONTENTS

(6) ๊ณต์ง€์‚ฌํ•ญ ๊ฒŒ์‹œํŒ์˜ ๋ชฉ๋ก์— ๋Œ€ํ•œ ์š”์ฒญ ์ฒ˜๋ฆฌ API

  • ํ˜•์‹ : REST API
  • HTTP METHOD : GET
  • ์š”์ฒญ ์ฃผ์†Œ :  "/api/notice"
  • return : ๋ฌธ์ž์—ด "๊ณต์ง€์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค."
/*
controller/NoticeController.java ์ƒ์„ฑ
*/

@RestController
public class NoticeController {
  
  @GetMapping("/api/notice")
  public String noticeString() {
    return "๊ณต์ง€์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค.";
  }
}


(7) ๊ณต์ง€์‚ฌํ•ญ ๊ฒŒ์‹œํŒ์˜ ๋ชฉ๋ก์— ๋Œ€ํ•œ ์š”์ฒญ ์ฒ˜๋ฆฌ API

  • ํ˜•์‹ : REST API
  • HTTP METHOD : GET
  • ์š”์ฒญ ์ฃผ์†Œ :  "/api/notice"
  • return : ๊ณต์ง€์‚ฌํ•ญ ๊ฒŒ์‹œํŒ์˜ ๋‚ด์šฉ์„ ์ถ”์ƒํ™”ํ•œ ๋ชจ๋ธ (๊ฒŒ์‹œ๊ธ€ID, ์ œ๋ชฉ, ๋‚ด์šฉ, ๋“ฑ๋ก์ผ)
    • ๊ฒŒ์‹œ๊ธ€ID = 1, ์ œ๋ชฉ = ๊ณต์ง€์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค., ๋‚ด์šฉ = ๊ณต์ง€์‚ฌํ•ญ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค., ๋“ฑ๋ก์ผ = 2021-2-8
/*
dto/NoticeDto.java ์ƒ์„ฑ
*/

@NoArgsConstructor
@AllArgsConstructor
@Builder
@Data
public class NoticeDto {

  //๊ฒŒ์‹œ๊ธ€ID, ์ œ๋ชฉ, ๋‚ด์šฉ, ๋“ฑ๋ก์ผ
  private long id;
  private String title;
  private String contents;
  private LocalDateTime regDate;

}

 

@RestController
public class NoticeController {

  @GetMapping("/api/notice")
  public NoticeDto notice() {

    NoticeDto noticeDto = new NoticeDto();

    noticeDto.setId(1);
    noticeDto.setTitle("๊ณต์ง€์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค.");
    noticeDto.setContents("๊ณต์ง€์‚ฌํ•ญ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.");
    noticeDto.setRegDate(LocalDateTime.of(2021,2,8,0,0));

    return noticeDto;
  }
}


(8) ๊ณต์ง€์‚ฌํ•ญ ๊ฒŒ์‹œํŒ์˜ ๋ชฉ๋ก์— ๋Œ€ํ•œ ์š”์ฒญ ์ฒ˜๋ฆฌ API

  • ํ˜•์‹ : REST API
  • HTTP METHOD : GET
  • ์š”์ฒญ ์ฃผ์†Œ :  "/api/notice"
  • return : ๊ณต์ง€์‚ฌํ•ญ ๊ฒŒ์‹œํŒ์˜ ๋‚ด์šฉ์„ ์ถ”์ƒํ™”ํ•œ ๋ชจ๋ธ (๊ฒŒ์‹œ๊ธ€ID, ์ œ๋ชฉ, ๋‚ด์šฉ, ๋“ฑ๋ก์ผ)์ด๋ฉฐ ๋ณต์ˆ˜ํ˜•ํƒœ์˜ ๋ฐ์ดํ„ฐ
    • ๊ฒŒ์‹œ๊ธ€ID = 1, ์ œ๋ชฉ = ๊ณต์ง€์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค., ๋‚ด์šฉ = ๊ณต์ง€์‚ฌํ•ญ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค., ๋“ฑ๋ก์ผ = 2021-1-30
    • ๊ฒŒ์‹œ๊ธ€ID = 2, ์ œ๋ชฉ = ๋‘๋ฒˆ์งธ ๊ณต์ง€์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค., ๋‚ด์šฉ = ๋‘๋ฒˆ์งธ ๊ณต์ง€์‚ฌํ•ญ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค., ๋“ฑ๋ก์ผ = 2021-1-31
@RestController
public class NoticeController {

  @GetMapping("/api/notice")
  public List<NoticeDto> notice() {

    List<NoticeDto> noticeDtoList = new ArrayList<>();

    NoticeDto noticeDto1 = new NoticeDto();
    noticeDto1.setId(1);
    noticeDto1.setTitle("๊ณต์ง€์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค.");
    noticeDto1.setContents("๊ณต์ง€์‚ฌํ•ญ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.");
    noticeDto1.setRegDate(LocalDateTime.of(2021,1,30,0,0));
    noticeDtoList.add(noticeDto1);

    NoticeDto noticeDto2 = new NoticeDto();
    noticeDto2.setId(2);
    noticeDto2.setTitle("๋‘๋ฒˆ์งธ ๊ณต์ง€์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค.");
    noticeDto2.setContents("๋‘๋ฒˆ์งธ ๊ณต์ง€์‚ฌํ•ญ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.");
    noticeDto2.setRegDate(LocalDateTime.of(2021,1,31,0,0));
    noticeDtoList.add(noticeDto2);

    return noticeDtoList;
  }
}


(9) ๊ณต์ง€์‚ฌํ•ญ ๊ฒŒ์‹œํŒ์˜ ๋ชฉ๋ก์— ๋Œ€ํ•œ ์š”์ฒญ ์ฒ˜๋ฆฌ API

  • ํ˜•์‹ : REST API
  • HTTP METHOD : GET
  • ์š”์ฒญ ์ฃผ์†Œ :  "/api/notice"
  • return : ๊ณต์ง€์‚ฌํ•ญ ๊ฒŒ์‹œํŒ์˜ ๋‚ด์šฉ์„ ์ถ”์ƒํ™”ํ•œ ๋ชจ๋ธ (๊ฒŒ์‹œ๊ธ€ID, ์ œ๋ชฉ, ๋‚ด์šฉ, ๋“ฑ๋ก์ผ)์ด๋ฉฐ ๋ณต์ˆ˜ํ˜•ํƒœ์˜ ๋ฐ์ดํ„ฐ
    • ์š”์ฒญํ•œ ๋‚ด์šฉ์ด ์—†๋Š” ๋นˆ ๋ชฉ๋ก์„ ๋ฆฌํ„ด
@RestController
public class NoticeController {

  @GetMapping("/api/notice")
  public List<NoticeDto> notice() {

    List<NoticeDto> noticeDtoList = new ArrayList<>();

    return noticeDtoList;
  }
}


(10) ๊ณต์ง€์‚ฌํ•ญ ๊ฒŒ์‹œํŒ์˜ ๋ชฉ๋ก ์ค‘ ์ „์ฒด ๊ฐœ์ˆ˜ ์ •๋ณด์— ๋Œ€ํ•œ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๋Š” API

  • ํ˜•์‹ : REST API
  • HTTP METHOD : GET
  • ์š”์ฒญ ์ฃผ์†Œ :  "/api/notice/count"
  • return : ๊ฒŒ์‹œํŒ์˜ ๊ฒŒ์‹œ๊ธ€ ๊ฐœ์ˆ˜(์ •์ˆ˜)๋ฅผ ๋ฆฌํ„ด
    • ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ์ •์ˆ˜ํ˜•์„ ๋ฆฌํ„ดํ•˜์˜€๋”๋ผ๋„ ํด๋ผ์ด์–ธํŠธ ์ชฝ์— ๋‚ด๋ ค๊ฐ€๋Š” ๋ถ€๋ถ„์€ ๋ฌธ์ž์—ด์ž„
@RestController
public class NoticeController {

  @GetMapping("/api/notice/count")
  public int noticeCount() {

    return 10;
  }
}


(11) ๊ณต์ง€์‚ฌํ•ญ ๊ฒŒ์‹œํŒ์˜ ๋ชฉ๋ก ์ค‘ ์ „์ฒด ๊ฐœ์ˆ˜ ์ •๋ณด์— ๋Œ€ํ•œ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๋Š” API

  • ํ˜•์‹ : REST API
  • HTTP METHOD : POST
  • ์š”์ฒญ ์ฃผ์†Œ :  "/api/notice"
  • return : ์ „๋‹ฌ๋˜๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” x-www-form-urlencoded ํ˜•์‹์˜ ์ œ๋ชฉ, ๋‚ด์šฉ์„ ์ž…๋ ฅ ๋ฐ›์Œ
    • ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ์ถ”์ƒํ™”ํ•˜์ง€ ์•Š๊ณ  ๊ธฐ๋ณธ๋ฐ์ดํ„ฐ ํƒ€์ž… ํ˜•ํƒœ๋กœ ์ „๋‹ฌ๋ฐ›์Œ 
    • ๋ฆฌํ„ด๊ฐ’์€ ์ž…๋ ฅ๋œ ํ˜•ํƒœ์— ๊ฒŒ์‹œ๊ธ€ID(1)์„ ์ถ”๊ฐ€ํ•˜์—ฌ ๋ชจ๋ธ ํ˜•ํƒœ๋กœ ๋ฆฌํ„ด
@RestController
public class NoticeController {

  @PostMapping("/api/notice")
  public NoticeDto addNotice(String title, String contents) {

    NoticeDto noticeDto = NoticeDto.builder()
        .id(1)
        .title(title)
        .contents(contents)
        .regDate(LocalDateTime.now())
        .build();

    return noticeDto;
  }
}


 

(12) ๊ณต์ง€์‚ฌํ•ญ ๊ฒŒ์‹œํŒ์˜ ๋ชฉ๋ก ์ค‘ ์ „์ฒด ๊ฐœ์ˆ˜ ์ •๋ณด์— ๋Œ€ํ•œ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๋Š” API

  • ํ˜•์‹ : REST API
  • HTTP METHOD : POST
  • ์š”์ฒญ ์ฃผ์†Œ :  "/api/notice"
  • return : ์ „๋‹ฌ๋˜๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” x-www-form-urlencoded ํ˜•์‹์˜ ์ œ๋ชฉ, ๋‚ด์šฉ์„ ์ž…๋ ฅ ๋ฐ›์Œ
    • ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ๊ณต์ง€์‚ฌํ•ญ ๋ชจ๋ธ๋กœ ์ถ”์ƒํ™”ํ•˜์—ฌ ์ „๋‹ฌ๋ฐ›์Œ
    • ๋ฆฌํ„ด๊ฐ’์€ ์ž…๋ ฅ๋œ ํ˜•ํƒœ์— ๊ฒŒ์‹œ๊ธ€ID(2) ๊ณผ ๋“ฑ๋ก์ผ์ž(ํ˜„์žฌ์‹œ๊ฐ„) ์ถ”๊ฐ€ํ•˜์—ฌ ๋ชจ๋ธ ํ˜•ํƒœ๋กœ ๋ฆฌํ„ด
@RestController
public class NoticeController {

  @PostMapping("/api/notice")
  public NoticeDto addNotice(NoticeDto noticeDto) {

    noticeDto.setId(2);
    noticeDto.setRegDate(LocalDateTime.now());

    return noticeDto;
  }
}


(13) ๊ณต์ง€์‚ฌํ•ญ ๊ฒŒ์‹œํŒ์˜ ๋ชฉ๋ก ์ค‘ ์ „์ฒด ๊ฐœ์ˆ˜ ์ •๋ณด์— ๋Œ€ํ•œ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๋Š” API

  • ํ˜•์‹ : REST API
  • HTTP METHOD : POST
  • ์š”์ฒญ ์ฃผ์†Œ :  "/api/notice"
  • return : ์ „๋‹ฌ๋˜๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” json ํ˜•์‹์˜ ์ œ๋ชฉ, ๋‚ด์šฉ์„ ์ž…๋ ฅ ๋ฐ›์Œ
    • ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ๊ณต์ง€์‚ฌํ•ญ ๋ชจ๋ธ๋กœ ์ถ”์ƒํ™”ํ•˜์—ฌ ์ „๋‹ฌ๋ฐ›์Œ
    • ๋ฆฌํ„ด๊ฐ’์€ ์ž…๋ ฅ๋œ ํ˜•ํƒœ์— ๊ฒŒ์‹œ๊ธ€ID(3) ๊ณผ ๋“ฑ๋ก์ผ์ž(ํ˜„์žฌ์‹œ๊ฐ„) ์ถ”๊ฐ€ํ•˜์—ฌ ๋ชจ๋ธ ํ˜•ํƒœ๋กœ ๋ฆฌํ„ด
@RestController
public class NoticeController {

  @PostMapping("/api/notice")
  public NoticeDto addNotice(@RequestBody NoticeDto noticeDto) {

    noticeDto.setId(3);
    noticeDto.setRegDate(LocalDateTime.now());

    return noticeDto;
  }
}


(14) ๊ณต์ง€์‚ฌํ•ญ์— ๊ธ€์„ ๋“ฑ๋กํ•˜๊ธฐ ์œ„ํ•œ ๊ธ€์ž‘์„ฑ์— ๋Œ€ํ•œ API

  • ํ˜•์‹ : REST API
  • HTTP METHOD : POST
  • ์š”์ฒญ ์ฃผ์†Œ :  "/api/notice"
  • return : ์ „๋‹ฌ๋˜๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” json ํ˜•์‹์˜ ์ œ๋ชฉ, ๋‚ด์šฉ์„ ์ž…๋ ฅ ๋ฐ›์Œ
    • ์ „๋‹ฌ๋œ ๊ฐ’์„ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ JPA Repository์™€ Entity๋ฅผ ํ†ตํ•ด์„œ Database์— ์ €์žฅ
    • ๋ฆฌํ„ด๊ฐ’์€ ์ €์žฅ๋œ id๊ฐ’์ด ํฌํ•จ๋œ Entity ๋ฆฌํ„ด
/*
entity/Notice.java ์ƒ์„ฑ
*/

@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
@Entity
public class Notice {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private long id;
  
  @Column
  private String title;

  @Column
  private String contents;

  @Column
  private LocalDateTime regDate;

}

 

/*
repository/NoticeRepository.java ์ƒ์„ฑ
*/

@Repository
public interface NoticeRepository extends JpaRepository<Notice, Long> {

}

 

@RequiredArgsConstructor
@RestController
public class NoticeController {
  
  private final NoticeRepository noticeRepository;

  @PostMapping("/api/notice")
  public Notice addNotice(@RequestBody NoticeDto noticeDto) {

    Notice notice = Notice.builder()
        .title(noticeDto.getTitle())
        .contents(noticeDto.getContents())
        .regDate(LocalDateTime.now())
        .build();
    noticeRepository.save(notice);

    return notice;
  }
}


(15) ๊ณต์ง€์‚ฌํ•ญ์— ๊ธ€์„ ๋“ฑ๋กํ•˜๊ธฐ ์œ„ํ•œ ๊ธ€์ž‘์„ฑ์— ๋Œ€ํ•œ API

  • ํ˜•์‹ : REST API
  • HTTP METHOD : POST
  • ์š”์ฒญ ์ฃผ์†Œ :  "/api/notice"
  • return : ์ „๋‹ฌ๋˜๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” json ํ˜•์‹์˜ ์ œ๋ชฉ, ๋‚ด์šฉ์„ ์ž…๋ ฅ ๋ฐ›์Œ
    • +) ๊ณต์ง€์‚ฌํ•ญ ์กฐํšŒ์ˆ˜์™€ ์กฐํšŒ์ˆ˜๋Š” ์ดˆ๊ธฐ๊ฐ’์„ 0์œผ๋กœ ์„ค์ •
    • ์ „๋‹ฌ๋œ ๊ฐ’์„ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ JPA Repository์™€ Entity๋ฅผ ํ†ตํ•ด์„œ Database์— ์ €์žฅ
    • ๋ฆฌํ„ด๊ฐ’์€ ์ €์žฅ๋œ id๊ฐ’์ด ํฌํ•จ๋œ Entity ๋ฆฌํ„ด
/*
entity/Notice.java ์— ์นผ๋Ÿผ ์ถ”๊ฐ€
*/
  
  @Column
  private int hits;

  @Column
  private int likes;

 

@RequiredArgsConstructor
@RestController
public class NoticeController {

  private final NoticeRepository noticeRepository;

  @PostMapping("/api/notice")
  public Notice addNotice(@RequestBody NoticeDto noticeDto) {

    Notice notice = Notice.builder()
        .title(noticeDto.getTitle())
        .contents(noticeDto.getContents())
        .regDate(LocalDateTime.now())
        .hits(0)
        .likes(0)
        .build();
   
    Notice resultNotice = noticeRepository.save(notice);

    return resultNotice;
  }
}


(16) ๊ณต์ง€์‚ฌํ•ญ์— ๊ธ€์„ ์ˆ˜์ •ํ•˜๊ธฐ ์œ„ํ•œ ์ƒ์„ธ์ •๋ณด ์š”์ฒญ์— ๋Œ€ํ•œ API

  • ํ˜•์‹ : REST API
  • HTTP METHOD : GET
  • ์š”์ฒญ ์ฃผ์†Œ :  "/api/notice/1" ("1"์€ ๊ณต์ง€์‚ฌํ•ญ์˜ ๊ธ€ID๋กœ ๋™์ ์œผ๋กœ ๋ณ€ํ•จ)
  • DB์—๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์ด๋ฏธ ์žˆ์Œ
  • return : ์กฐํšŒ๋œ ๊ฒฐ๊ณผ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ Entity ๋ฆฌํ„ด, ์—†๋Š” ๊ฒฝ์šฐ null return
@RequiredArgsConstructor
@RestController
public class NoticeController {

  private final NoticeRepository noticeRepository;

  @GetMapping("/api/notice/{id}")
  public Notice notice(@PathVariable Long id) {

    Optional<Notice> notice = noticeRepository.findById(id);
    if(notice.isPresent()) {
      return notice.get();
    }
    return null;
  }
}


(17) ๊ณต์ง€์‚ฌํ•ญ์— ๊ธ€์„ ์ˆ˜์ •ํ•˜๊ธฐ ์œ„ํ•œ ๊ธ€์ˆ˜์ •์— ๋Œ€ํ•œ API

  • ํ˜•์‹ : REST API
  • HTTP METHOD : PUT
  • ์š”์ฒญ ์ฃผ์†Œ :  "/api/notice/1" ("1"์€ ๊ณต์ง€์‚ฌํ•ญ์˜ ๊ธ€ID๋กœ ๋™์ ์œผ๋กœ ๋ณ€ํ•จ)
  • ํŒŒ๋ผ๋ฏธํ„ฐ : json ํ˜•์‹์˜ ๊ณต์ง€์‚ฌํ•ญ ๊ธ€ID, ์ œ๋ชฉ, ๋‚ด์šฉ์„ ์ž…๋ ฅ ๋ฐ›์Œ
  • ๊ณต์ง€์‚ฌํ•ญ ์ˆ˜์ •์ผ์€ ํ˜„์žฌ์‹œ๊ฐ„์„ ์ €์žฅ, ๊ณต์ง€์‚ฌํ•ญ ์กฐํšŒ์ˆ˜์™€ ์ข‹์•„์š” ์ˆ˜๋Š” ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์Œ
  • ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ๊ฒฝ์šฐ๋Š” Data๋งคํ•‘์— ๋Œ€ํ•œ Entity๋กœ ํ•„์š”์—†๋Š” ํ•ญ๋ชฉ๊นŒ์ง€ ๋ฐ›์ง€ ๋ง๊ณ  ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋งŒ ์ž…๋ ฅ๋ฐ›๊ฒŒ ์ž‘์„ฑ
  • DB์—๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์ด๋ฏธ ์žˆ์Œ
  • ์ „๋‹ฌ๋œ ๊ฐ’์„ ์ˆ˜์ •ํ•˜๊ธฐ ์œ„ํ•œ JPA Repository์™€ Entity๋ฅผ ํ†ตํ•ด์„œ Database์— ์ˆ˜์ •
/*
entity/Notice.java ์— ์นผ๋Ÿผ ์ถ”๊ฐ€
*/
  @Column
  private LocalDateTime updateDate;

 

@RequiredArgsConstructor
@RestController
public class NoticeController {

  private final NoticeRepository noticeRepository;

  @PutMapping ("/api/notice/{id}")
  public void updateNotice(@PathVariable Long id, @RequestBody NoticeDto noticeDto) {

    Optional<Notice> notice = noticeRepository.findById(id);
    if(notice.isPresent()) {
      notice.get().setTitle(noticeDto.getTitle());
      notice.get().setContents(noticeDto.getContents());
      notice.get().setUpdateDate(LocalDateTime.now());
      noticeRepository.save(notice.get());
    }
  }
}


(18,19) ๊ณต์ง€์‚ฌํ•ญ์— ๊ธ€์„ ์ˆ˜์ •ํ•˜๊ธฐ ์œ„ํ•œ ๊ธ€์ˆ˜์ •์— ๋Œ€ํ•œ API

  • ํ˜•์‹ : REST API
  • HTTP METHOD : PUT
  • ์š”์ฒญ ์ฃผ์†Œ :  "/api/notice/1" ("1"์€ ๊ณต์ง€์‚ฌํ•ญ์˜ ๊ธ€ID๋กœ ๋™์ ์œผ๋กœ ๋ณ€ํ•จ)
  • ํŒŒ๋ผ๋ฏธํ„ฐ : json ํ˜•์‹์˜ ๊ณต์ง€์‚ฌํ•ญ ๊ธ€ID, ์ œ๋ชฉ, ๋‚ด์šฉ์„ ์ž…๋ ฅ ๋ฐ›์Œ
  • ๊ณต์ง€์‚ฌํ•ญ ์ˆ˜์ •์ผ์€ ํ˜„์žฌ์‹œ๊ฐ„์„ ์ €์žฅ, ๊ณต์ง€์‚ฌํ•ญ ์กฐํšŒ์ˆ˜์™€ ์ข‹์•„์š” ์ˆ˜๋Š” ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์Œ
  • ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ๊ฒฝ์šฐ๋Š” Data๋งคํ•‘์— ๋Œ€ํ•œ Entity๋กœ ํ•„์š”์—†๋Š” ํ•ญ๋ชฉ๊นŒ์ง€ ๋ฐ›์ง€ ๋ง๊ณ  ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋งŒ ์ž…๋ ฅ๋ฐ›๊ฒŒ ์ž‘์„ฑ
  • ๊ณต์ง€์‚ฌํ•ญ์˜ ๊ธ€์ด ์กด์žฌํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ ์˜ˆ์™ธ์‚ฌํ•ญ์„ ๋ฐœ์ƒ
  • ์˜ˆ์™ธ์ฒ˜๋ฆฌ๋Š” ExceptionHandler๋ฅผ ํ†ตํ•ด์„œ ๊ตฌํ˜„ํ•˜๊ณ , ๋ฐœ์ƒํ•˜๋Š” ์˜ˆ์™ธ์— ๋Œ€ํ•ด์„œ๋Š” 400, ์˜ˆ์™ธ ๋ฉ”์„ธ์ง€๋ฅผ ๋ฆฌํ„ด
/*
exception/NoticeNotFoundException.java ์ƒ์„ฑ
*/
public class NoticeNotFoundException extends RuntimeException{
  public NoticeNotFoundException(String message) {
    super(message);
  }
}

 

@RequiredArgsConstructor
@RestController
public class NoticeController {

  private final NoticeRepository noticeRepository;

  @ExceptionHandler(NoticeNotFoundException.class)
  public ResponseEntity<String> handlerNoticeNotFoundException(NoticeNotFoundException exception) {

    return new ResponseEntity<>(exception.getMessage(), HttpStatus.BAD_REQUEST);
  }

  @PutMapping ("/api/notice/{id}")
  public void updateNotice(@PathVariable Long id, @RequestBody NoticeDto noticeDto) {
    /*
    Optional<Notice> notice = noticeRepository.findById(id);
    if(!notice.isPresent()) {
      //์˜ˆ์™ธ ๋ฐœ์ƒ
      throw new NoticeNotFoundException("๊ณต์ง€์‚ฌํ•ญ์˜ ๊ธ€์ด ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.");
    }
    */
    Notice notice = noticeRepository.findById(id)
        .orElseThrow(() -> new NoticeNotFoundException("๊ณต์ง€์‚ฌํ•ญ์˜ ๊ธ€์ด ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค."));

    //๊ณต์ง€์‚ฌํ•ญ ๊ธ€์ด ์žˆ์„ ๋•Œ
    notice.setTitle(noticeDto.getTitle());
    notice.setContents(noticeDto.getContents());
    notice.setUpdateDate(LocalDateTime.now());
    noticeRepository.save(notice);
  }
}


(20) ๊ณต์ง€์‚ฌํ•ญ์— ๊ธ€์˜ ์กฐํšŒ์ˆ˜๋ฅผ ์ฆ๊ฐ€์‹œํ‚ค๋Š” API

  • ํ˜•์‹ : REST API
  • HTTP METHOD : PATCH
  • ์š”์ฒญ ์ฃผ์†Œ :  "/api/notice/1/hits" ("1"์€ ๊ณต์ง€์‚ฌํ•ญ์˜ ๊ธ€ID๋กœ ๋™์ ์œผ๋กœ ๋ณ€ํ•จ)
@RequiredArgsConstructor
@RestController
public class NoticeController {

  private final NoticeRepository noticeRepository;

  @ExceptionHandler(NoticeNotFoundException.class)
  public ResponseEntity<String> handlerNoticeNotFoundException(NoticeNotFoundException exception) {

    return new ResponseEntity<>(exception.getMessage(), HttpStatus.BAD_REQUEST);
  }

  @PatchMapping("/api/notice/{id}/hits")
  public void noticeHits(@PathVariable Long id) {

    Notice notice = noticeRepository.findById(id)
        .orElseThrow(() -> new NoticeNotFoundException("๊ณต์ง€์‚ฌํ•ญ์˜ ๊ธ€์ด ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค."));

    notice.setHits(notice.getHits() + 1);
    noticeRepository.save(notice);
  }


(21,22) ๊ณต์ง€์‚ฌํ•ญ์˜ ๊ธ€์„ ์‚ญ์ œํ•˜๊ธฐ ์œ„ํ•œ API

  • ํ˜•์‹ : REST API
  • HTTP METHOD : DELETE
  • ์š”์ฒญ ์ฃผ์†Œ :  "/api/notice/1" ("1"์€ ๊ณต์ง€์‚ฌํ•ญ์˜ ๊ธ€ID๋กœ ๋™์ ์œผ๋กœ ๋ณ€ํ•จ)
  • ์ „๋‹ฌ๋ฐ›์€ ๊ณต์ง€์‚ฌํ•ญ์˜ ๋‚ด์šฉ์ด ์กฐํšŒ๊ฐ€ ๋˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ NotFoundException ๋ฐœ์ƒ
  • ์ด์— ๋Œ€ํ•œ ๊ฒฐ๊ณผ๋Š” 400์—๋Ÿฌ์™€ "๋‚ด์šฉ์ด ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค." ๋ผ๋Š” ๋ฉ”์‹œ์ง€ ๋ฆฌํ„ด
@RequiredArgsConstructor
@RestController
public class NoticeController {

  private final NoticeRepository noticeRepository;

  @ExceptionHandler(NoticeNotFoundException.class)
  public ResponseEntity<String> handlerNoticeNotFoundException(NoticeNotFoundException exception) {

    return new ResponseEntity<>(exception.getMessage(), HttpStatus.BAD_REQUEST);
  }
  
  @DeleteMapping("/api/notice/{id}")
  public void deleteNotice(@PathVariable Long id) {

    Notice notice = noticeRepository.findById(id)
        .orElseThrow(() -> new NoticeNotFoundException("๊ณต์ง€์‚ฌํ•ญ์˜ ๊ธ€์ด ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค."));
    
    noticeRepository.delete(notice);
  }


(23) ๊ณต์ง€์‚ฌํ•ญ์˜ ๊ธ€์„ ์‚ญ์ œํ•˜๊ธฐ ์œ„ํ•œ API

  • ํ˜•์‹ : REST API
  • HTTP METHOD : DELETE
  • ์š”์ฒญ ์ฃผ์†Œ :  "/api/notice/1" ("1"์€ ๊ณต์ง€์‚ฌํ•ญ์˜ ๊ธ€ID๋กœ ๋™์ ์œผ๋กœ ๋ณ€ํ•จ)
  • ๊ฒŒ์‹œํŒ์˜ ๊ธ€์„ ๋ฌผ๋ฆฌ์ ์œผ๋กœ ์‚ญ์ œํ•˜์ง€ ์•Š๊ณ  ์‚ญ์ œ ํ”Œ๋ž˜๊ทธ๊ฐ’์„ ์ด์šฉํ•˜์—ฌ ์‚ญ์ œ ์ง„ํ–‰
  • ์‚ญ์ œ์ผ์‹œ๋Š” ํ˜„์žฌ ์‹œ๊ฐ„์œผ๋กœ ์„ค์ •
  • ๊ณต์ง€์‚ฌํ•ญ์˜ ๊ธ€์ด ์ด๋ฏธ ์‚ญ์ œ๋œ ๊ฒฝ์šฐ๋Š” 200์ฝ”๋“œ์™€ "์ด๋ฏธ ์‚ญ์ œ๋œ ๊ธ€์ž…๋‹ˆ๋‹ค."๋ผ๋Š” ๋ฉ”์‹œ์ง€ ๋ฆฌํ„ด
/*
entity/Notice.java ์— ์นผ๋Ÿผ ์ถ”๊ฐ€
*/
  @Column
  private boolean deleted; //๋ฐ์ดํ„ฐ ๊ธฐ๋ณธ๊ฐ’ 0์œผ๋กœ ๋ณ€๊ฒฝ

  @Column
  private LocalDateTime deletedDate;

 

/*
exception/AlreadyDeletedException.java ์ƒ์„ฑ
*/
public class AlreadyDeletedException extends RuntimeException{
  public AlreadyDeletedException(String message) {
    super(message);
  }
}

 

@RequiredArgsConstructor
@RestController
public class NoticeController {

  private final NoticeRepository noticeRepository;

  @ExceptionHandler(AlreadyDeletedException.class)
  public ResponseEntity<String> handlerAlreadyDeletedException(AlreadyDeletedException exception) {

    return new ResponseEntity<>(exception.getMessage(), HttpStatus.BAD_REQUEST);
  }

  @ExceptionHandler(NoticeNotFoundException.class)
  public ResponseEntity<String> handlerNoticeNotFoundException(NoticeNotFoundException exception) {

    return new ResponseEntity<>(exception.getMessage(), HttpStatus.BAD_REQUEST);
  }

  @DeleteMapping("/api/notice/{id}")
  public void deleteNotice(@PathVariable Long id) {

    Notice notice = noticeRepository.findById(id)
        .orElseThrow(() -> new NoticeNotFoundException("๊ณต์ง€์‚ฌํ•ญ์˜ ๊ธ€์ด ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค."));

    if (notice.isDeleted()) {
      throw new AlreadyDeletedException("์ด๋ฏธ ์‚ญ์ œ๋œ ๊ธ€์ž…๋‹ˆ๋‹ค.");
    }
    notice.setDeleted(true);
    notice.setDeletedDate(LocalDateTime.now());
    noticeRepository.save(notice);
  }
}

 


(24) ๊ณต์ง€์‚ฌํ•ญ์˜ ๊ธ€์„ ์‚ญ์ œํ•˜๊ธฐ ์œ„ํ•œ API

  • ํ˜•์‹ : REST API
  • HTTP METHOD : DELETE
  • ์š”์ฒญ ์ฃผ์†Œ :  "/api/notice
  • ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๊ธ€์„ ๋™์‹œ์— ์‚ญ์ œํ•˜๊ธฐ ์œ„ํ•ด์„œ noticeId ๋ชฉ๋ก์„ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋ฐ›์•„์„œ ํ•ด๋‹น ๊ณต์ง€์‚ฌํ•ญ์˜ ๊ธ€์„ ์‚ญ์ œ
/*
Dto/NoticeDeleteDto.java ์ƒ์„ฑ
*/
@Data
public class NoticeDeleteDto {

  private List<Long> idList;

}

 

/*
repository/NoticeRepository.java ๋ณ€๊ฒฝ
*/
@Repository
public interface NoticeRepository extends JpaRepository<Notice, Long> {

  Optional<List<Notice>> findByIdIn(List<Long> idList);

}

 

@RequiredArgsConstructor
@RestController
public class NoticeController {

  private final NoticeRepository noticeRepository;

  @ExceptionHandler(NoticeNotFoundException.class)
  public ResponseEntity<String> handlerNoticeNotFoundException(NoticeNotFoundException exception) {

    return new ResponseEntity<>(exception.getMessage(), HttpStatus.BAD_REQUEST);
  }

  @DeleteMapping("/api/notice")
  public void deleteNoticeList(@RequestBody NoticeDeleteDto noticeDeleteDto) {
    List<Notice> noticeList = noticeRepository.findByIdIn(noticeDeleteDto.getIdList())
        .orElseThrow(() -> new NoticeNotFoundException("๊ณต์ง€์‚ฌํ•ญ์˜ ๊ธ€์ด ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค."));

    noticeList.forEach(e -> {
      e.setDeleted(true);
      e.setDeletedDate(LocalDateTime.now());
    });
    noticeRepository.saveAll(noticeList);
  }

(25) ๊ณต์ง€์‚ฌํ•ญ์˜ ๊ธ€์„ ์‚ญ์ œํ•˜๊ธฐ ์œ„ํ•œ API

  • ํ˜•์‹ : REST API
  • HTTP METHOD : DELETE
  • ์š”์ฒญ ์ฃผ์†Œ :  "/api/notice/all"
@RequiredArgsConstructor
@RestController
public class NoticeController {

  private final NoticeRepository noticeRepository;

  @DeleteMapping("/api/notice/all")
  public void deleteAll( ) {

    noticeRepository.deleteAll();

  }


(26) ๊ธ€์„ ์ž‘์„ฑํ•  ๋•Œ ์ œ๋ชฉ๊ณผ ๋‚ด์šฉ์„ ๋ฐ›์•„์„œ ์ €์žฅํ•˜๋Š” API

  • ํ˜•์‹ : REST API
  • HTTP METHOD : POST
  • DTO๋ฅผ ํ†ตํ•œ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ํ˜•ํƒœ๋กœ ๋ฐ›์Œ
  • ๋“ฑ๋ก์ผ์€ ํ˜„์žฌ์ผ์‹œ, ์กฐํšŒ์ˆ˜/์ข‹์•„์ˆ˜๋Š” 0์œผ๋กœ ์„ค์ •
  • ์ „๋‹ฌ๋ฐ›์€ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ํ†ตํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅํ•จ
@RequiredArgsConstructor
@RestController
public class NoticeController {

  private final NoticeRepository noticeRepository;

  @PostMapping("/api/notice")
  public Notice addNotice(@RequestBody NoticeDto noticeDto) {

    Notice notice = Notice.builder()
        .title(noticeDto.getTitle())
        .contents(noticeDto.getContents())
        .regDate(LocalDateTime.now())
        .hits(0)
        .likes(0)
        .build();
   
    Notice resultNotice = noticeRepository.save(notice);

    return resultNotice;
  }
}

(27) ๊ธ€์„ ์ž‘์„ฑํ•  ๋•Œ ์ œ๋ชฉ๊ณผ ๋‚ด์šฉ์„ ๋ฐ›์•„์„œ ์ €์žฅํ•˜๋Š” API

  • ํ˜•์‹ : REST API
  • HTTP METHOD : POST
  • ์ž…๋ ฅ๊ฐ’์€ ์ž…๋ ฅDTO๋ฅผ ํ†ตํ•ด์„œ ์ž…๋ ฅ๋ฐ›์Œ
  • ์ œ๋ชฉ๊ณผ ๋‚ด์šฉ์€ ํ•„์ˆ˜ ์ž…๋ ฅ ์กฐ๊ฑด(์ž…๋ ฅ๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ 400๋ฆฌํ„ด
  • ์˜ˆ์™ธ๋ฐœ์ƒ์‹œ ๊ฐ๊ฐ์˜ ์—๋Ÿฌ๋ฅผ ์ทจํ•ฉํ•˜์—ฌ ์ฝœ๋ ‰์…˜ ํ˜•ํƒœ๋กœ ๋ฆฌํ„ด
/*
build.gradle์— ์ถ”๊ฐ€
*/
implementation("org.springframework.boot:spring-boot-starter-validation")

 

/*
dto/NoticeDto.java ์ˆ˜์ •
*/
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Data
public class NoticeDto {

  //๊ฒŒ์‹œ๊ธ€ID, ์ œ๋ชฉ, ๋‚ด์šฉ, ๋“ฑ๋ก์ผ
  private long id;
  
  @NotBlank(message = "์ œ๋ชฉ์€ ํ•„์ˆ˜ ํ•ญ๋ชฉ์ž…๋‹ˆ๋‹ค.")
  private String title;

  @NotBlank(message = "๋‚ด์šฉ์€ ํ•„์ˆ˜ ํ•ญ๋ชฉ์ž…๋‹ˆ๋‹ค.")
  private String contents;
  
  private LocalDateTime regDate;

}

 

/*
config/ResponseError.java ์ƒ์„ฑ
*/
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Data
public class ResponseError {
  private String field;
  private String message;
  
  public static ResponseError of(ObjectError e) {
    return ResponseError.builder()
        .field(((FieldError) e).getField())
        .message(e.getDefaultMessage())
        .build();
  }
}

 

@RequiredArgsConstructor
@RestController
public class NoticeController {

  private final NoticeRepository noticeRepository;

  @PostMapping("/api/notice")
  public ResponseEntity<?> addNotice(@RequestBody @Valid NoticeDto noticeDto, Errors errors) {

    if (errors.hasErrors()) {
      List<ResponseError> responseErrors = new ArrayList<>();

      errors.getAllErrors().forEach(e -> {
      
// ์ด๋ ‡๊ฒŒ๋„ ๊ฐ€๋Šฅ      
//        ResponseError responseError = new ResponseError();
//        responseError.setField(((FieldError) e).getField());
//        responseError.setMessage(e.getDefaultMessage());
//        responseErrors.add(responseError);

          responseErrors.add(ResponseError.of((FieldError)e));
      });
      return new ResponseEntity<>(responseErrors, HttpStatus.BAD_REQUEST);
    }

    //์ •์ƒ์ ์ธ ์ €์žฅ
    Notice notice = Notice.builder()
        .title(noticeDto.getTitle())
        .contents(noticeDto.getContents())
        .likes(0)
        .hits(0)
        .regDate(LocalDateTime.now())
        .build();
    noticeRepository.save(notice);

    return ResponseEntity.ok().build();
  }
}


(28) ๊ธ€์„ ์ž‘์„ฑํ•  ๋•Œ ์ œ๋ชฉ๊ณผ ๋‚ด์šฉ์„ ๋ฐ›์•„์„œ ์ €์žฅํ•˜๋Š” API

  • ํ˜•์‹ : REST API
  • HTTP METHOD : POST
  • ์ž…๋ ฅ๊ฐ’์€ ์ž…๋ ฅDTO๋ฅผ ํ†ตํ•ด์„œ ์ž…๋ ฅ๋ฐ›์Œ
  • ์ œ๋ชฉ๊ณผ ๋‚ด์šฉ์€ ํ•„์ˆ˜ ์ž…๋ ฅ ์กฐ๊ฑด(์ž…๋ ฅ๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ 400๋ฆฌํ„ด)
  • +) ์ œ๋ชฉ์˜ ๊ฒฝ์šฐ 10์ž ์ด์ƒ 100์ž ์ดํ•˜๋กœ ์ž…๋ ฅ
  • +) ๋‚ด์šฉ์˜ ๊ฒฝ์šฐ 50์ž ์ด์ƒ 1000์ž ์ดํ•˜๋กœ ์ž…๋ ฅ
  • ์˜ˆ์™ธ๋ฐœ์ƒ์‹œ ๊ฐ๊ฐ์˜ ์—๋Ÿฌ๋ฅผ ์ทจํ•ฉํ•˜์—ฌ ์ฝœ๋ ‰์…˜ ํ˜•ํƒœ๋กœ ๋ฆฌํ„ด
/*
dto/NoticeDto.java ์ˆ˜์ •
*/
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Data
public class NoticeDto {

  //๊ฒŒ์‹œ๊ธ€ID, ์ œ๋ชฉ, ๋‚ด์šฉ, ๋“ฑ๋ก์ผ
  private long id;
  
  @NotBlank(message = "์ œ๋ชฉ์€ ํ•„์ˆ˜ ํ•ญ๋ชฉ์ž…๋‹ˆ๋‹ค.")
  @Size(min = 10, max = 100, message = "์ œ๋ชฉ์€ 10-100์ž ์‚ฌ์ด์˜ ๊ฐ’์ž…๋‹ˆ๋‹ค.")
  private String title;

  @NotBlank(message = "๋‚ด์šฉ์€ ํ•„์ˆ˜ ํ•ญ๋ชฉ์ž…๋‹ˆ๋‹ค.")
  @Size(min = 50, max = 1000, message = "๋‚ด์šฉ์€ 10-100์ž ์‚ฌ์ด์˜ ๊ฐ’์ž…๋‹ˆ๋‹ค.")
  private String contents;

  private LocalDateTime regDate;

}


(29) ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ๊ณต์ง€์‚ฌํ•ญ ๋ชฉ๋ก ์ค‘์—์„œ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ „๋‹ฌ๋œ ๊ฐœ์ˆ˜๋งŒํผ ์ตœ๊ทผ ๊ณต์ง€์‚ฌํ•ญ์„ ๋ฆฌํ„ดํ•˜๋Š” API

  • ex) ์ตœ๊ทผ 2๊ฐœ
@RequiredArgsConstructor
@RestController
public class NoticeController {

  private final NoticeRepository noticeRepository;

  @GetMapping("/api/notice/latest/{size}")
  public Page<Notice> noticeLatest(@PathVariable int size) {
    Page<Notice> noticePage = noticeRepository.findAll(PageRequest.of(0, size, Sort.Direction.DESC, "regDate"));

    return noticePage;
  }
}

 


(30) ๊ณต์ง€์‚ฌํ•ญ์˜ ๋‚ด์šฉ์„ ๋“ฑ๋กํ•œ ์ดํ›„์— ๋ฐ”๋กœ ๋™์ผํ•œ ์ œ๋ชฉ๊ณผ ๋‚ด์šฉ์˜ ๊ณต์ง€์‚ฌํ•ญ์„ ๋“ฑ๋กํ•˜๋Š” ๊ฒฝ์šฐ ๋“ฑ๋ก์„ ๋ง‰๋Š” API

  • ์ค‘๋ณต ๊ฒฝ์šฐ (์กฐ๊ฑด : ๋™์ผ์ œ๋ชฉ, ๋™์ผ๋‚ด์šฉ๊ณผ ๋“ฑ๋ก์ผ์ด ํ˜„์žฌ์‹œ๊ฐ„ ๊ธฐ์ค€ 1๋ถ„ ์ด๋‚ด์˜ ๊ฒฝ์šฐ๋Š” ์ค‘๋ณต์œผ๋กœ ํŒ๋‹จํ•จ)
  • ์˜ˆ์™ธ๋ฐœ์ƒ (DuplicateNoticeException)
/*
repository/NoticeRepository.java ๋ณ€๊ฒฝ
*/
@Repository
public interface NoticeRepository extends JpaRepository<Notice, Long> {


  //๊ฒฝ์šฐ 1
  Optional<List<Notice>> findByTitleAndContentsAndRegDateIsGreaterThanEqual(String title, String contents, LocalDateTime regDate);

  //๊ฒฝ์šฐ 2
  int countByTitleAndContentsAndRegDateIsGreaterThanEqual(String title, String contents, LocalDateTime regDate);

}

 

/*
exception/DuplicateNoticeException.java ์ƒ์„ฑ
*/
public class DuplicateNoticeException extends RuntimeException{
  public DuplicateNoticeException(String message) {
    super(message);
  }
}

 

@RequiredArgsConstructor
@RestController
public class NoticeController {

  private final NoticeRepository noticeRepository;

  @ExceptionHandler(DuplicateNoticeException.class)
  public ResponseEntity<String> handlerDuplicateNoticeException(DuplicateNoticeException exception) {

    return new ResponseEntity<>(exception.getMessage(), HttpStatus.BAD_REQUEST);
  }

  @PostMapping("/api/notice")
  public void addNotice(@RequestBody NoticeDto noticeDto) {

    //์ค‘๋ณต์ฒดํฌ
    LocalDateTime checkDate = LocalDateTime.now().minusMinutes(1);

// ๊ฒฝ์šฐ1
//  Optional<List<Notice>> noticeList = noticeRepository.findByTitleAndContentsAndRegDateIsGreaterThanEqual(
//      noticeDto.getTitle(),
//      noticeDto.getContents(),
//      checkDate);
//  if (noticeList.isPresent()) {
//    if (noticeList.get().size() > 0) {
//      throw new DuplicateNoticeException("1๋ถ„์ด๋‚ด์˜ ๋“ฑ๋ก๋œ ๋™์ผํ•œ ๊ณต์ง€์‚ฌํ•ญ์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.");
//    }

//๊ฒฝ์šฐ 2
    int noticeCount = noticeRepository.countByTitleAndContentsAndRegDateIsGreaterThanEqual(
        noticeDto.getTitle(),
        noticeDto.getContents(),
        checkDate);
    if (noticeCount > 0) {
        throw new DuplicateNoticeException("1๋ถ„์ด๋‚ด์˜ ๋“ฑ๋ก๋œ ๋™์ผํ•œ ๊ณต์ง€์‚ฌํ•ญ์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.");
      }

    Notice notice = Notice.builder()
        .title(noticeDto.getTitle())
        .contents(noticeDto.getContents())
        .likes(0)
        .hits(0)
        .regDate(LocalDateTime.now())
        .build();
    noticeRepository.save(notice);

  }
}

728x90
๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€