REST API 2

WebStudy/Spring / / 2021. 7. 20. 23:42

HATEOAS를 이용한 자기주소정보 표현

  • REST API의 문제 상황
    • REST API를 이용하는 클라이언트들은 하나의 트랜잭션 안에서 여러 API를 사용하는 경우
    • 기본이 되는 URI는 공통으로 사용하지만 하위 파라미터나 하위 URL에 대해서는 인지하지 못하는 경우
  • 이유
    • 전체 URI는 요청 파라미터에 따라 변경될 수 있기 때문
  • HATEOAS를 이용해서 해당 결과를 얻을 수 있는 전체 URI를 반환할 수 있는 정보를 제공할 수 있음
    • 클라이언트는 해당 정보를 통해 해당 결과를 얻을 수 있는 전체 URI 정보를 알 수 있음

HATEOAS를 이용한 URI 정보 표현

설정

  • 라이브러리 추가
    • compile("org.springframework.boot:spring-boot-starter-hateoas")
public class TodoResource extends ResourceSupport {
    private String title;
    public TodoResource() {}
    public TodoResource(String title) { this.title = title; }
    public String getTitle() { return title; }
    public void setTitle(String title) { this.title = title; }
}
@RequestMapping(value = "/todoh", method = RequestMethod.GET)
public ResponseEntity<TodoResource> geth(@RequestParam(value = "todoTitle") String todoTitle){
    TodoResource todoResource = new TodoResource(todoTitle);
    todoResource.add(linkTo(methodOn(BasicController.class).geth(todoTitle)).withSelfRel());
    return  new ResponseEntity(todoResource, HttpStatus.OK);
}

REST API 문서화

Spring과 swagger를 이용

  • Spring API 문서 페이지를 자동 생성해서 지속적으로 동기화 할 수 있도록 함

swagger 설정 및 라이브러리 추가

  • swagger
    • swagger-UI
      • API 정보를 JSON으로 매핑해서 문서로 생성
    • swagger-editor
      • swagger 문서를 작성
    • 언어별 swagger SDK
  • 의존성 추가
  • compile group: 'io.springfox', name: 'springfox-swagger2', version: '2.4.0' compile group: 'io.springfox', name: 'springfox-swagger-ui', version: '2.4.0'
  • SwaggerConfig 클래스 생성
    • 기본 생성을 하면 Basic Controller 하나만 만들었지만 다른 것들도 추가로 표시됨
      • 따라서, Docket의 설정을 변경해 basic으로 변경해 줌
        • 컨트롤러의 기본 URI가 basic으로 시작하므로
  • @Configuration
    @EnableSwagger2
    @Profile({"dev"})
    public class SwaggerConfig {
        @Bean
        public UiConfiguration uiConfig() {
            return UiConfiguration.DEFAULT;
        }
    
        private ApiInfo metadata() {
            return new ApiInfoBuilder()
                    .title("JPub Spring Boot")
                    .description("Spring Boot Rest API")
                    .version("1.0")
                    .build();
        }
    
        @Bean
        public Docket api() {
            return new Docket(DocumentationType.SWAGGER_2)
                    .groupName("basic")
                    .select()
                    .apis(RequestHandlerSelectors.any())
                    .paths(regex("/basic/.*"))
                    .build()
                    .apiInfo(metadata());
        }
    
    }

REST 클라이언트 개발

  • 업무별로 API를 만들어서 서로 API 간 통신을 통해 데이터를 주고 받는 경우가 많음
  • API 서버를 만들기 위해서 다른 서버 API를 연동해야 하는 일도 있음

RestTemplate

  • RestTemplate
    • 스프링 MVC 라이브러리에 포함된 클래스
    • 대게 클라이언트 라이브러리의 제공 형태는 get, post와 같은 HTTP 메서드에 대응되는 메서드들을 제공
    • 다양한 메시지 컨버터를 내장
      • JSON 응답을 Map 또는 모델 클래스로 간편하게 변환해서 사용
    • Apache httpClient에 대한 의존성
  • RestTemplate 의존성 추가
    • compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.2'

RestTemplate 네트워크 속성 설정

  • 이는 안해도 무관
    • 안한다면, Timeout 설정에 따라 성능 이슈가 발생 할 수 있음
  • HttpClient와 관련된 설정은 HttpComponentsClientHttpRequestFactory 클래스의 인스턴스를 이용함
    • set 메서드를 이용해서 설정
      public HttpComponentsClientHttpRequestFactory restTemplate() {
        HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
        factory.setReadTimeout(READ_TIMEOUT);
        factory.setConnectTimeout(CONNECT_TIMEOUT);
        RestTemplate restTemplate = new RestTemplate(factory);
        return factory;
      }
    • RequestConfig를 이용해서 설정 후 그 인스턴스를 통해 초기화
      public HttpComponentsClientHttpRequestFactory restTemplate() {
        RequestConfig config = RequestConfig.custom()
            .setConnectTimeout(timeout)
            .setConnectionRequestTimeout(timeout)
            .setSocketTimeout(timeout)
            .build();
        ClosealbeHttpClient httpClient = HttpClientBuilder
            .create()
            .setMaxConnTotal(MAX_CONN_TOTAL)
            .setMaxConnPerRoute(config)
            .build();
        factory.setHttpClient(httpClient);
        RestTemplate restTemplate = new RestTemplate(factory);
        return new HttpComponentsClientHttpRequestFactory(httpClient);
      }

UriComponentsBuilder 활용

  • UriComponentsBuilder
    • Builder 방식으로 URI를 만드는데 필요한 정보들을 메서드를 이용해 만들 수 있으며 인코딩도 가능하다.
    • RestTemplate을 이용해서 POST 방식으로 데이터를 요청할 때
      • MultiValueMap을 사용해서 데이터를 전달해야 하지만 이를 이용하면 따로 만들지 않아도 됨

UriComponentsBuilder 생성

  • 생성자의 접근 제한자가 protected
    • 직접 호출 불가
    • 메서드 체이닝 방식으로 URI를 구성하는데 필요한 정보들을 추가
      • UriComponentsBuilder.newInstance().schem().method().method.
  • http:, ftp:, https: 이와 같은 정보는 프로토콜을 의미함
    • UriComponentsBuilder에서는 scheme 정보에 해당

UriComponentsBuilder로 파라미터 전달

UriComponentsBuilder.newInstance().schem("http")
    .host("movie.naver.com")
    .port(80)
    .path("/movie/bi/mi/basic.nhn")
    .queryParam("code", 146506)
    .build()
    .encode()
    .toUri();
  • 다수의 파라미터 일 경우 queryParam를 추가해서 사용

UriComponent로 PathVariable이 포함된 URL 만들기

  • API uri 자체가 파라미터가 되는 상황도 있음
UriComponentsBuilder.newInstance().schem("http")
    .host("test.book.com")
    .port(80)
    .path("/book/{bookId}")
    .build().expand(bookId)
    .encode()
    .toUri();
  • uri를 {}로 감싸고 expand 메서드를 추가함으로 PathVariable에 해당하는 변숫값 전달

'WebStudy > Spring' 카테고리의 다른 글

Boot Starter  (0) 2021.07.22
Annotation  (0) 2021.07.21
REST API 1  (0) 2021.07.19
정적 자원 관리와 템플릿 엔진  (0) 2021.07.17
Spring Boot  (0) 2021.07.16
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기