북 스터디/스프링 부트 핵심 가이드

[스프링 부트] 04장 ~ 05장

dbssk 2023. 5. 28. 06:10

이 글은 '스프링 부트 핵심 가이드 - 스프링 부트를 활용한 애플리케이션 개발 실무' 책을 통해 학습한 내용을 정리한 글입니다.

04장. 스프링 부트 애플리케이션 개발하기

  • 프로젝트 생성
    • spring initializer를 통해 생성
    • 프로젝트 이름, 생성할 위치, 언어, 타입(Gradle, Maven), 그룹과 아티팩트, 자바 버전, 패키지 생성 옵션 선택
    • 의존성은 프로젝트를 생성할 때 추가 가능하고, 생성 이후에도 추가 가능

  • Maven / Gradle 
    • maven : pom.xml 파일에 프로젝트 설정과 의존성 관리
    • gradle : build.gradle 파일에서 프로젝트 설정과 의존성 관리

05장. API를 작성하는 다양한 방법

GET API

1. @RequestMapping

@RequestMapping(value = "/data", method = RequestMethod.GET)
public String getData() {
    // 데이터를 가져오는 로직 구현
    return "Data";
}

2. @PathVariable

@GetMapping("/data/{id}")
public String getDataById(@PathVariable("id") int id) {
    // id에 해당하는 데이터를 가져오는 로직 구현
    return "Data with ID: " + id;
}

3. @RequestParam

@GetMapping("/data")
public String getDataByQueryParam(@RequestParam("param") String param) {
    // param에 해당하는 데이터를 가져오는 로직 구현
    return "Data with param: " + param;
}

4. DTO 객체를 활용

@GetMapping("/data")
public String getDataByDTO(DataRequestDto requestDto) {
    // requestDto의 값을 활용하여 데이터를 가져오는 로직 구현
    return "Data with DTO: " + requestDto.toString();
}

POST API

1. @RequestMapping

@RequestMapping(value = "/data", method = RequestMethod.POST)
public String saveData() {
    // 데이터를 저장하는 로직 구현
    return "Data saved";
}

@PostMapping("/data")
public String saveData() {
	// 데이터를 저장하는 로직 구현
    return "Data saved";
}

2. @RequestBody

@RequestBody 어노테이션을 사용하여 request body의 데이터를 매개변수로 받아와서 처리

@PostMapping("/data")
public String saveDataWithRequestBody(@RequestBody DataRequestDto requestDto) {
    // requestDto의 값을 활용하여 데이터를 저장하는 로직 구현
    return "Data saved with request body: " + requestDto.toString();
}

PUT API

1. @RequestBody

@PutMapping 어노테이션을 사용하여 경로 변수와 request body의 데이터를 매개변수로 받아 업데이트 작업을 수행

@PutMapping("/data/{id}")
public String updateData(@PathVariable("id") int id, @RequestBody DataRequestDto requestDto) {
    // id에 해당하는 데이터를 업데이트하는 로직 구현
    // requestDto의 값을 활용하여 업데이트 작업 수행
    return "Data with ID " + id + " updated";
}

2. ResponseEntity

ResponseEntity를 활용하여 업데이트 결과에 따른 상태 코드와 메시지를 반환하는 방식

public ResponseEntity<String> updateData(@PathVariable("id") int id, @RequestBody DataRequestDto requestDto) {
    // id에 해당하는 데이터를 업데이트하는 로직 구현
    // requestDto의 값을 활용하여 업데이트 작업 수행

    if (업데이트가_성공적으로_수행되었는지) {
        return ResponseEntity.ok("Data with ID " + id + " updated");
    } else {
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Failed to update data");
    }
}

DELETE API

1. @PathVariable & @RequestParam

@DeleteMapping("/data/{id}")
public String deleteDataById(@PathVariable("id") int id, @RequestParam("param") String param) {
    // id와 param에 해당하는 데이터를 삭제하는 로직 구현
    return "Data with ID " + id + " and param " + param + " deleted";
}

Swagger

Swagger를 사용하면 API의 설명, 요청/응답 형식, 매개변수, 응답 코드 등을 명세화하여 자동으로 API 문서를 생성할 수 있다.

Swagger를 사용하기 위해서는 pom.xml 또는 build.gradle 파일에 의존성을 추가해야 한다. 그리고 Swagger와 관련된 설정 코드를 작성해야 하는데 com.springboot.api 하단에 config라는 패키지를 생성한 후에 그 안에 생성하는 것이 좋다.

@Configuration
@EnableSwagger2
public class SwaggerConfig {

    @Bean
    public Docket api() {
        return new Docket(DocumentationType.SWAGGER_2)
        		.apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.example.api"))
                .paths(PathSelectors.any())
                .build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("Sample API Documentation")
                .description("API documentation for Sample Application")
                .version("1.0.0")
                .build();
    }
}

대표적인 어노테이션

  1. @Api : 컨트롤러 클래스에 적용되며, 해당 컨트롤러를 Swagger 문서에 포함시킨다.
  2. @ApiOperation : API 메서드에 적용되며, 해당 메서드의 작업(operation)에 대한 설명을 추가한다.
  3. @ApiParam : 메서드의 매개변수에 적용되며, 매개변수에 대한 설명을 추가한다.
  4. @ApiModel @ApiModelProperty : DTO 클래스에 적용되며, DTO 모델에 대한 설명과 각 필드의 설명을 추가한다.

예시 코드

@RestController
@RequestMapping("/api")
@Api(tags = "Sample API")
public class SampleController {

    @GetMapping("/data/{id}")
    @ApiOperation("Get data by ID")
    public ResponseEntity<Data> getDataById(
            @PathVariable("id") @ApiParam("Data ID") int id) {
        // 데이터 조회 로직 구현
        Data data = ...;
        return ResponseEntity.ok(data);
    }

    @PostMapping("/data")
    @ApiOperation("Create new data")
    public ResponseEntity<Data> createData(
            @RequestBody @ApiParam("New data") DataRequestDto requestDto) {
        // 데이터 생성 로직 구현
        Data createdData = ...;
        return ResponseEntity.status(HttpStatus.CREATED).body(createdData);
    }
}

Logback

Logback은 자바 애플리케이션에서 로깅을 처리하기 위한 라이브러리이다. Logback은 SLF4J(Simple Logging Facade for Java)의 구현체로서, SLF4J와 함께 사용된다. 그리고 각 클래스에 logger 객체를 만들어서 사용한다.

private static final Logger logger = LoggerFactory.getLogger(LogbackExample.class);

 

5가지 로그 레벨

  • debug & trace : 가장 낮은 중요도를 가지며, 개발자가 시스템의 동작을 상세히 추적하고 디버깅하기 위해 사용된다.

  • info : 시스템의 주요 이벤트나 중요한 상태 변경과 같은 정보성 메시지를 나타낸다. 시스템이 정상적으로 작동하고 있는지 확인하는데 유용하다. 예를 들어, 서비스가 시작되거나 중지되는 경우, 사용자가 로그인하는 경우 등이 info 레벨의 메시지로 기록될 수 있다.
  • warning : 경고 메시지를 나타낸다. 시스템에서 잠재적인 문제가 발생했거나 잠재적인 오류 상황에 직면했음을 나타낸다.

  • error : 심각한 문제나 오류가 발생했음을 나타낸다. 시스템의 정상적인 운영에 문제가 있음을 나타내며, 주로 예외 처리, 오류 디버깅 및 시스템 문제 해결을 위해 사용된다.
  • critical : 가장 높은 중요도를 가지며, 시스템의 심각한 장애를 나타낸다. 시스템이 중단되거나 회복 불가능한 오류가 발생했음을 나타내며, 시스템의 가용성과 안전성에 직접적인 위협이 된다. 주로, 시스템 관리자나 운영팀에게 심각한 문제를 알리는데 사용된다.