[SpringBoot] 게시판 기본 CRUD 기능 구현하기[1]

Euiyeon Park·2025년 2월 8일
post-thumbnail

✨ 구현을 통한 학습 목표

  1. URL, Http Method를 활용한 기본 라우팅 방법 학습
  2. Request Body, Query Params, Path Params 사용
  3. ✅ ORM 사용 - 엔티티 생성, 기본 CRUD 활용
  4. ✅ 요청과 응답까지의 과정 경험
  5. ✅ REST API 설계
  6. ✅ Http Status Code

✨ 클라이언트가 서버로 데이터를 전달하는 방법

1. @RequestBody

  • Http 요청의 본문(body)에 데이터를 담아 서버로 전송하는 방식
  • JSON, XML, Form-data 등으로 데이터를 전송
  • 주로 POST, PUT, PATCH 등의 요청에서 주로 사용
  • 요청 데이터를 Jackson 라이브러리를 사용해 객체로 변환
{
    "title": "제목이에옹",
    "content": "내용이에옹"
}
@RestController
@RequestMapping("/boards")
public class BoardController {

    @PostMapping
    public String createPost(@RequestBody PostRequest request) {
        return "Post Title:" + request.getTitle();
    }
}
  • JSON이 요청 본문으로 전달되면 @RequestBody가 이 내용을 자바 객체(PostReqeust)로 변환

2. @RequestParam

  • URL의 쿼리 문자열에 데이터를 전달받을 때 사용
  • URL의 ? 뒤에 key=value 형식으로 데이터를 전달하는 방식
  • 주로 GET 요청에서 주로 사용

💡 @RequestParam에서 자주 사용되는 속성

  1. required (기본값: true)
  • 요청 파라미터가 필수인지 여부를 설정
  • true인 경우, 해당 파라미터가 없으면 400 Bad Request 오류 발생
  • false로 설정하면 파라미터가 없어도 요청이 처리됨 - 파라미터값은 null
  1. defaultValue
  • 파라미터 값이 없을 때 기본값을 지정할 수 있음
  • 문자열로 지정되므로, 숫자 또는 Boolean 등 변환이 필요하면 자동 변환
  1. name
  • 요청 파라미터의 이름을 변경할 수 있음
  • 파라미터 이름이 다른 경우 사용
GET /user?uid=123   →  User ID: 123
@GetMapping("/user")
public String getUser(@RequestParam(name = "uid") String userId) {
    return "User ID: " + userId;
}

3. @PathVariable

  • URL 경로의 일부로 데이터를 전달하는 방식 - 먼소리임?
  • URL의 일부를 변수처럼 사용해서 데이터를 전달하는 방식
  • RESTful API에서 특정 리소스를 식별할 때 자주 사용
GET /users/1
  • 1id} 부분에 들어가서 컨트롤러의 id값으로 매핑
@RestController
@RequestMapping("/users")
public class UserController {

    @GetMapping("/{id}")
    public String getUserById(@PathVariable Long id) {
        return "User ID: " + id;
    }
}

💫 언제 뭘 사용하는게 좋을까?

  1. @RequestBody : JSON 데이터를 전송할 때
  2. @RequestParam : 필터링, 정렬 등 검색 조건을 전달할 때
  3. @PathVariable : 사용자 id 등 특정 리소스를 식별할 때

✨ 엔티티 id 자동 생성 - Auto Increment

1. @GeneratedValue

  • JPA에서 기본 키(PK)값을 자동 생성할 때 사용하는 어노테이션
  • ID값을 수동으로 설정하지 않아도, 자동으로 증가되도록 함
  • strategy 속성을 사용해 어떤 방식으로 ID를 생성할지 설정 가능

2. GenerationType

  • ID를 생성하는 전략을 결정하는 값

💡 GenerationType의 종류

⚠️ IDENTITY 전략은 JPA가 ID값을 미리 알 수 없어서 batch insert 최적화 불가능

전략설명특징
IDENTITYDB의 AUTO_INCREMENT 기능 사용MySQL, PostgreSQL 등에서 사용
SEQUENCEDB의 SEQUENCE 객체 사용Oracle, PostgreSQL 등에서 사용
TABLE키 값을 저장하는 별도 테이블 사용자주 사용❌
AUTODB에 맞게 자동 선택DB에 따라 적절한 전략을 자동으로 선택

@Entity
public class Post {
	
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private String title;

    @Column(nullable = false)
    private String content;

    @CreationTimestamp
    @Column(name="created_at", updatable = false)
    private LocalDateTime createdAt;
}

✨ Http Status Code

  • 구현 제약조건 중 "Http Status Code 규약에 맞게 응답 코드 설정"이 있어 부랴부랴 코드를 수정했다.✏️
  • 제약조건을 만족하기 위해 Controller와 Service 레이어의 메서드 반환타입을
    모두 ResponseEntity<T>로 변경했다.
  1. 생성의 경우 HttpStatus.CREATED 반환(201)
  2. 조회의 경우, HttpStatus.OK 반환(200)
  3. 수정의 경우, HttpStatus.OK 반환(200)
  4. 삭제의 경우, HttpStatus.NO_CONTENT 반환(204)
    // 게시글 작성
    @PostMapping("/post")
    public ResponseEntity<PostResponse> savePost(@RequestBody @Valid PostCreateRequest request){
        return postService.savePost(request);
    }
    // 게시글 작성
    public ResponseEntity<PostResponse> savePost(PostCreateRequest request){
        Post savedPost = postRepository.save(new Post(request));
        return ResponseEntity.status(HttpStatus.CREATED).body(new PostResponse(savedPost));
    }

💫 반환타입으로 Http Status Code를 지정하지 않으면?

  • 게시글 생성, 조회, 수정, 삭제 등의 CRUD 기능을 수행할 때
    ResponseEntity.status로 상태코드를 지정하지 않으면 어떤 코드가 전달될까?
  • ResponseEntity에 대해 알아보자 !!!

✨ ResponseEntity<T>

  • ResponseEntity<T>는 Spring에서 HTTP응답을 표현하는 클래스
    헤더 정보, 상태 코드(HttpStatus), 응답 본문(body)을 함께 반환할 수 있도록 한다.

💫 ResponseEntity의 주요 특징

1. HTTP 상태 코드 포함

  • 응답의 HTTP 상태코드를 명확하게 지정 가능 - HttpStatus.CREATED, HttpStatus.OK 등

2. 응답 본문 설정 가능

  • ResponseEntity<T>에서 T에 해당하는 객체를 JSON 형태로 반환 가능

3. 헤더 설정 가능

  • ResponseEntity.headers()를 통해 추가적인 응답 헤더 설정 가능

그래서 반환타입에서 ResponseEntityHttpStatus를 사용하지 않으면 어떻게 되냐구!

💫 1. Controller에서 ResponseEntity를 사용하지 않는 경우

  • 컨트롤러에서 ResponseEntity<T>를 사용하지 않고 단순히 객체를 반환하면,
    Spring은 자동으로 HTTP 응답을 구성한다.
@PostMapping("/post")
public PostResponse savePost(@RequestBody @Valid PostCreateRequest request) {
    return postService.savePost(request);
}

📍 Spring의 동작

  • PostResponse 객체가 반환되면, Spring은 기본적으로 HttpStatus 200 OK로 설정
  • 이 경우 응답 본문(body)는 존재하지만, 명확한 상태 코드 지정은 불가능
  • 예외 발생 시 Spring이 적절한 HttpStatus를 설정하지만, 개발자가 세밀하게 제어❌

💫 2. Service에서 ResponseEntity를 사용하지 않는 경우

  • 서비스에서도 ResponseEntity<T>를 사용하지 않는다면, 단순히 PostResponse 객체를 반환
public PostResponse savePost(PostCreateRequest request){
    Post savedPost = postRepository.save(new Post(request));
    return new PostResponse(savedPost);
}

📍 이런 경우에는?

  • 서비스 메서드는 PostResponse 객체만 반환
  • 컨트롤러가 이 값을 받아 그대로 반환하면, HTTP 상태코드는 기본값 200 OK로 설정

결론 - ResponseEntity와 HttpStatus를 사용하는 이유

  1. 클라이언트에게 명확한 상태 코드 제공
  2. 응답 본문과 함께 상태 코드 및 헤더를 설정해 세밀한 제어 가능
  3. 예외 처리 및 응답 구조를 표준화 해 RESTful API의 일관성 유지
  4. ResponseEntity와 HttpStatus를 사용하지 않을 경우 200 OK만 반환되어 상태 구분이 어려움
profile
"개발자는 해결사이자 발견자이다✨" - Michael C. Feathers

0개의 댓글