[RestAPI] RESTful Web Services 개발

wony·2024년 4월 29일

Spring

목록 보기
23/33

개요. 스프링 부트를 이용한 RESTful

  • section0 : Web Service & Web Application
  • section1 : Spring Boot로 개발하는 RESTful API
  • section2 : User Service API 추가
  • section3 : Restful service 기능 확장
  • section4 : Spring Boot API 사용
  • section5 : JPA 사용
  • section6 : REST API 설계 가이드

섹션0 : Web Service & Web Application

1. Web Service 개발 방법 SOAP과 REST의 이해

REST(Representational State Transfer):

  • REST란 정보를 나타내고 전달하는 방식입니다.
  • HTTP Method를 사용하여 데이터를 처리합니다.
    예시: 인터넷에서 사진을 보는 것처럼, 정보를 표현하고 전달하는 방식입니다.

SOAP(Simple Object Access Protocol):

  • 무엇을 의미하는가? SOAP는 간단한 객체 접근 프로토콜로, 웹 서비스 간에 통신할 때 사용됩니다. 이는 XML 기반의 메시지를 사용하여 데이터를 교환합니다.
  • 특징: 보안과 신뢰성이 높습니다. 주로 기업 간 시스템 간 통신에 사용됩니다.
  • 예시: 원격 서버에 데이터를 요청하고 응답을 받는 과정에서 SOAP를 사용할 수 있습니다.
  • 주의할 점: SOAP는 REST보다 더 많은 오버헤드가 발생할 수 있으며, 구현이 복잡할 수 있습니다.

2. RESTful

  • REST API를 제공하는 웹 서비스

  • Resource

    • URI, 인터넷 자원을 나타내는 유일한 주소
    • XML, HTML, JSON
  • Endpoint

    • API를 통해 서버가 제공하는 리소스에 접근하기 위해서 제공되는 주소
    • ex) 블로그의 게시물을 가져오기 위한 엔드포인트는 다음과 같을 수 있습니다: https://example.com/api/posts/{post_id}
    • 여기서 {post_id}는 특정 게시물의 ID를 가리키며, 이 엔드포인트를 통해 클라이언트는 해당 ID를 가진 게시물에 대한 정보를 요청할 수 있습니다.

섹션1. Spring Boot로 개발하는 RESTful Service

1) RESTful API 설계 – 사용자 관리 API

사용자가 여러 개의 글을 작성할 수 있다고 가정하고 설계(1:N)

1) 사용자 목록조회를 위해 /users를 사용하고 GET HTTP Method사용
2) 새로운 사용자 등록도 /users를 사용하고 POST HTTP Method 사용
3) 사용자 한 명 반환 /users/{id} GET HTTP Method사용
4) 사용자 삭제 /users/{id} Delete HTTP Method사용
5) 사용자의 모든 포스트 반환 /users/{id}/posts Get Method 사용
6) 사용자의 모든 포스트 생성 /users/{id}/posts POST Method 사용
7) 사용자의 모든 details 반환 /users/{id}/posts/{post_id} Get Method 사용

1. HelloWorld Controller 추가

1) HelloWorldController라는 클래스를 추가

  • 이 컨트롤러 클래스가 스프링 컨텍스트에 등록되기 위해서는
    REST 컨트롤러라는 어노테이션 작업을 해야 한다.
  • 일단 만들고자 하는 RESTful 서비스에는 화면단을 가지고 있지 않기 때문에 컨트롤러가 아니라 RestController를 사용한다.

2) 애노테이션에 @GetMapping(path = "/hello-world") 추가
이렇게 추가하면 전달하고자 하는 HTTP 의 메소드가 무엇인지 따로 명시하지 않아도 이 AnnotationGetMethod라고 바로 알 수 있다.

3) helloWorld라는 메소드를 추가해준다.

2. HelloWorld Bean추가

1) @Getmapping(path = “/hello-world-bean”) 추가

2) helloWorldBean 메서드가 HelloWorldBean 클래스를 반환할 수 있도록 코드 작성

3) HelloWorldBean 클래스는 @Data(롬복 – getter,setter 다 자동생성), @AllArgsConstructor 를 추가하여 생성자 자동 생성 어노테이션을 추가해준다.

  • AllArgsConstructor클래스의 모든 필드를 인자로 받는 생성자를 만들어주고, RequiredArgsConstructorfinal 이나 @NotNull으로 표시된 필드만을 인자로 받는 생성자를 만들어줍니다.

3. DispatcherServlet과 프로젝트 동작의 이해

SpringBoot의 설정파일 : application.yml or application.properties

application.properties -> 설정이름 = 값
application.yml -> 설정이름:값

  • yml 파일을 쓰게 되면 계층 구조로 구분할 수 있기 때문에 같은 이름의 그룹핑이 되어 있다고 하면 훨씬 더 적은 데이터 양을 가지고 동일한 속성을 지정할 수 있다.
  • 따라서, 좀 더 구조적으로 컴팩트한 설정을 할 수 있다는 특징을 가지고 있습니다.

1. Spring Boot Auto Configuration

  • DispatcherServlet(디스패처 서블릿)

    • 클라이언트의 모든 요청을 한곳으로 받아서 처리한다. 요청에 맞는 Handler 로 요청을 전달하고, Handler 의 실행 결과를 Http Response 형태로 만들어서 반환한다.
    • ErrorMvcAutoConfiguration (에러 처리를 위해)
    • HttpMessageConverterAutoConfiguration -> JSON convert
      사용자 요청에 따른 비즈니스 로직을 처리하고 나온 결과값을 API로 호출한 사용자 혹은 클라이언트로 보내줘야 한다. 전달하기 위한 데이터 포맷 처리를 위한 것

2. Rest Controller

  • @Controller + @ResponseBody
  • View 를 갖지 않는 REST data(JSON/XML)을 변환

  • 스프링 MVC 에서 사용하고자 하는 뷰 형태의 페이지를 생성할 필요가 없기 때문에 클라이언트 요청 값을 바로 JSON 포맷으로 변경해서 전달하는 것만 신경 쓰면 된다.
  • 추가로, RseponseBody에 추가하는 작업을 따로 하지 않더라도 자동적으로 RseponseBody에 담겨서 반환되기 때문에 추가 작업 필요 없다.

4. Path Variable - 가변 URI 사용

  • @PathVariable스프링 프레임워크에서 컨트롤러 메소드에서 가변적인 URI 값을 받아오기 위해 사용되는 어노테이션입니다.
  • 가변적인 URIURL 의 경로 부분이 변할 수 있는 경우를 말합니다.
  • 예를 들어, 다음과 같은 URL이 있다고 가정해봅시다.

http://localhost:8080/books/{id}

  • 여기서 {id} 부분은 가변적인 값이 될 수 있습니다.
  • 클라이언트가 요청할 때 이 부분에 어떤 값을 넣느냐에 따라 다른 동작을 하도록 하고 싶다면 @PathVariable을 사용합니다.
@GetMapping("/books/{id}")
public ResponseEntity<Book> getBookById(@PathVariable Long id) {
    // id를 이용하여 해당하는 책 정보를 가져와 반환
}
  • 위의 예제에서 @PathVariable 어노테이션은 메소드 파라미터로 선언된 id 에 해당하는 URL 경로의 가변 값 을 매핑해줍니다.

  • 즉, 클라이언트가 요청한 URL 에서 {id} 에 해당하는 값을 자동으로
    id 변수 에 매핑하여 메소드 내에서 사용할 수 있도록 해줍니다.

  • 이렇게 함으로써 사용자가 요청한 가변적인 URL의 값이 컨트롤러 메소드 내에서 사용될 수 있게 됩니다.

  • 따라서 클라이언트가 지정한 값이 실제 URL에 사용될 수 있게 됩니다.

섹션2. User service API 구현

1. User 도메인 클래스 생성

  • 1) User 클래스 생성
    • @Data를 사용하면 자동으로 getter,setter 생성
    • @AllArgsConstructor사용하면 자동으로 생성자 생성
  • 2) UserDaoService라는 비즈니스 로직 생성
    • (finaAll, save, findOne) 생성

2. 사용자 목록 조회를 위한 API 구현 - HTTP GET method

  • 1) 사용자 요청을 처리할 수 있는 컨트롤러 추가
    • UserController 이전에 추가했던 서비스 클래스의 인스턴스를 선언한 다음에 비즈니스 메서드들을 작성.
    • 스프링에서는 개발자가 직접 서비스의 인스턴스를 생성해서 사용하는 것이 아니라 스프링 프레임 워크 내에서 사용 가능한 인스턴스들이 빈이란 이름으로써 스프링 컨텍스트에 의해서 관리되고 있다.
    • 따라서, 필요한 인스턴스가 있을 경우에는 해당 인스턴스에 대해서 스프링 컨텍스트에 등록이 되고 호출하는 방식으로 사용.

스프링이 가동이 될 때, 이 user.dao.service 라는 것이 스프링 컨텍스트 메모리 안에 등록이 되고 그걸 주입 받아서 사용. 스프링의 빈은 용도에 따라서 컨트롤러 빈 , 서비스 빈 , 레포지토리 빈 같이 나눠서 사용한다.

3. 사용자 등록을 위한 API 구현 - HTTP POST method

  • 1) 클라이언트가 사용자에게 어떠한 정보를 전달할 때는 PostMapping을 사용합니다.
  • 2) JSON 이라던가 XML 형태로 전달하기 위해서 Controller 에서는 해당하는 매개변수 타입을 @RequestBody라는 타입으로 받아서 작업을 해줘야 한다.
  • 3) 그러면 클라이언트에서 전달하는 데이터의 포맷과 일치하는 필드의 값을 찾아서 우리가 유저라는 데이터 값에다가 자동으로 매핑 시켜주는 작업을 처리해주게 된다.

4. HTTP Status Code 제어

서버에서 PostMethod에 대한 처리를 한 다음에 정상적인 처리가 되었을 때, 기존의 200번이 아닌 다른 번호로 바꾸는 것이 가능하다.

  • 1) 이를 위해 ServletUriComponentsBuilder를 사용할 것.
  • 2) 서버에서 반환하려는 데이터는 ResponseEntity에 담아서 반환하자.
    즉, 이전에 만들었던 createUser 메서드를 void에서 ResponseEntity로 반환하는 것임!

  • 3) 제일 마지막에 보면 return 값이 하나 필요하게 되었다. ResponseEntity 값을 하나 생성할 건데 created 다음에 우리는 주소값을 같이 포함시켜서 반환시켜 줄 것입니다.
  • 4) servletUriComponentBuilder라는 것을 사용하고 request 정보로부터 URI 를 생성할 것입니다. 이를 saverdUser 값에서 id값을 가지고 와서 조합할 것이고 완성이 되면 toUri 라는 메소드 가지고 전체 정보를 Uri 로 바꾸고 로케이션 정보를 response 엔티티에 전달하게 되면 200번 ok가 201번 created라는 요청 값으로 변경이 됩니다.

5. HTTP status Code 제어 위한 Exception Handling(예외 처리)

  • user id 존재하지 않을 때도 200 OK를 반환하는 경우가 존재한다.
    이를 해결하기 위해 throw new UserNotFoundException 추가
  • 이때, @ResponseStatus(HttpStatus.NOT_FOUND) 사용해서 404 에러 발생시키기

1) 이를 위해 UserControllerretrieveAllUsers 코드 수정
(null이면 예외 던지기)

2) 1번과 같이 수정하면 아래 클래스가 없다고 하기 때문에 UserNotFoundException 클래스 생성

3) 이렇게 한 다음 https://127.0.0.1:8088/users/4 라고 하면 없기 때문에 에러 발생. 그러나, UserNotFoundException에 반드시 HttpStatus.NOT_FOUND를 해야 404 에러가 발생한다

6. Spring AOP를 이용한 Exception Handling

UserNotFoundException와 같이 예외적인 Exception말고 일반화된 예외클래스를 사용해서 상태 코드 혹은 클라이언트에게 보여줘야 하는 메시지를 제어해보자.

  • 1) 이 예외 클래스를 위해서 ExceptionResponse 클래스를 선언함
  • 2)CustomizedResponseEntityExceptionHandler 추가. 이때, @ControllerAdvice 애너테이션을 사용해서 모든 컨트롤러가 실행될 때 반드시 해당하는 CustomizedResponseEntityExceptionHandler가 실행될 수 있도록 한다.
  • 3) CustomizedResponseEntityExceptionHandler 여기에 ResponseEntityExceptionHandler 상속받는다.
  • 4) CustomizedResponseEntityExceptionHandler 클래스에 handleAllException, handleUserNotFoundException 메서드도 만든다.
  • 여기서 SpringAOP란 어떤 로직을 기준으로 핵심적인 관점이라던가 부가적인 관점으로 봤을 때, 관점을 기준으로 모듈화 하겠다는 의미.
  • 5) 이렇게 하면 결과적으로 긴 에러 메시지가 아니라, timestamp, message, details 관련 에러 메시지가 발생하게 됩니다.

7. 사용자 삭제를 위한 API 구현 – HTTP DELETE method

1) ControllerIterator로 표현할 예정
2) UserdeleteUser 추가

profile
안녕하세요. wony입니다.

0개의 댓글