카테고리 없음

RESTful API

서버관리자 페페 2024. 4. 11. 18:41

마이크로서비스 아키텍쳐에는 애플리케이션 기능을 RESTful API로 노출하는것이 일반적이다

 

-

 

1. 스프링부트로 RESTful APi를 설계하고 구축하는 방법

2. 응답 데이터 규격, HTTP 응답코드 등 API 사용자에게 필요한 정보를 문서화하여 제공하는 방법

3. API를 테스트하기위해 단위 테스트를 작성하는 방법

4. RESTful API에 보안을 적용하여 보호하는 방법

 

-

REST 아키텍쳐 스타일을 따르는 API

 

REpresentational State Transefer

클라이언트가 서버에 있는 자원을 요청하면 서버는 해당 자원의 상태를 규격에 맞게 표현한 정보를 반환한다

 

Represntation : 상태 정보 : JSON / 단순 문자열 / HTML 등 여러가지 형식 중 특히 JSON

 

-

 

스프링부트는 REST API 설계와 구축을 프레임워크 차원에서 지원

 

-

 

사용시 기능1 : 백엔드와 프런트엔드UI 사이의 결합을 끊어낼 수 있으며 앵귤러, 리액트, 뷰 등 자유롭게 원하는 FE 프레임워크를 선택해서 사용할 수 있다

 

-

 

POJO로 course 클래스 를 만든다

 

리포지토리 작성

 

서비스 : API에서 제공하는 연산으로 구성된 인터페이스를 정의하고 추가로 구현체를 작성하는게 좋음

컨트롤러에서 특정 구현체에 의존하는 대신 인터페이스에 의존해서 사용자 요청을 처리하도록

(기능 수정되더라도 컨트롤러에서 변경X)

 

컨트롤러는 @RestController =  @Controlller + @ResponseBody

메타 어노테이션

리스폰스바디는 메서드의 반환값이 HTTP 응답 본문에 자동 바인딩됨

 

-

 

create하는 Post의 요청본문(payload)는  @RequestBody 로 들어온다

JSON으로 전달되며 이 JSON에 매핑되는 POJO클래스를 넣는다 (DTO 대신)

JSON을 POJO 객체로 디시리얼리제이션하는것은 스프링부트가 자동으로 수행

 

-

 

Put으로 업데이트 역시 마찬가지, 단 put은 변경 대상인 id도 pathVariable로 받을것

 

-

 

REST 엔드포인트 테스트

 

포스트맨 : GUI를 통해 편리하게 엔드포인트를 호출하고 테스트 

EP를 모아 그룹으로 관리 가능, 내보내서 공유 가능, 내보낸 정보는 가져와서 재사용 가능

 

터미널을 사용하는게 좋다면 -> cURL이나 HTTPie

cURL -> 유닉스 내장

HTTPie -> 터미널에서 실행되는 HTTP 클라이언트로서 HTTP URL 호출 가능

 

-

 

> http POST : 8080/courses/1 HTTP/1.1 200

 

-

 

JSON 변환에는 기본적으로 Jackson 라이브러리 사용

 

엔드포인트에는 명사의 복수형 사용

Courses / Persons / Vehicles

동사는 어차피 HTTP 메서드에 들어있으니 굳이 복잡하게 할 필요없다

 

-----------------------예외 처리---------------------

CourseNotFoundException 런타임익셉션 상속해서 개설

 

코스서비스Impl 중 findBy에 orElseThrow  넣어준뒤 String.format으로 에러메시지 처리

 

컨트롤러에서 직접 처리하지않고, 글로벌로 @ControllerAdvice 처리한다

 

---------------------테스트----------------------

@AutoConfigureMockMvc

ObjectMapper 인스턴스 만들어서 자바객체-제이슨 직렬화한다

andExepect

 

 

------------------문서화-------------------

OpenAPI 명세는 RESTful API를 문서화하는 표준을 제공, API 사용자가 API 기능을 일관성있게 파악

 

디펜던시 추가 - > 스웨거까지 자동으로 만들어짐

 

컨트롤러에 해당 어노테이션 제공

@Tag

@ResponseStatus

@Operation

 

@SpringBootApplication에 OpenAPI 빈 생성

apllication.yml에 값 미리 넣어두기

 

-

 

기본 제공되는 uri에 접속하면 HTML / JSON으로 문서를 얻을 수 있다

코드젠 -> JSON으로부터 클라이언트 애플리케이션 생성

 

-----------------REST API 버저닝-----------------

URI

요청 파라미터

커스텀 HTTP 헤더

미디어 타입

 

-----------------보안--------------

JWT 토큰 사용

인가 서버를 거침(키클록 사용)

 

디펜던시 추가

 

@AuthenticationPrincipal 사용해서 JWT 저장된 값에 접근가능

 

IDOR 이슈 : insecure direct object reference 

엔드포인트에서는 토큰의 유효성만 체크할뿐, 누구의 토큰인지 구분 x

-> @PreAuthorize / @PostAuthorize 와 SpEL를 사용해서 단순 토큰 유효성 외에 추가적인 접근 제어 적용가능

 

= 메서드 수준 시큐리티 필요

 

메인 클래스에 @EnableGlobalMethodSecurity(prePostEnabled = true) 추가로 시작

원하는 메서드에 @PostAuthorize("@getAuthor.apply(returnObject, principal.clains['user_name'])")

 

BiFunction에서 메서드 내 코스의 author. userid를 비교 로직 실행

 

-> 403 : 인증에는 성공했지만 인가되지않음

 

-

 

SCOPE 도 사용가능

해당 스코프를 포함하고 있는 토큰만 엔드포인트에 접근

ex) 서드파티 클라이언트 애플리케이션에게 특정 강사가 개설한 모든 과정을 조회할 수 있게 해주지만, 저장은 할 수 없게 하고 싶을때

 

@PreAuthorize("hasAuthority('SCOPE_course:read)')")

 

 

스프링 시큐리티는 filterChain과 여러 필터를 사용해서 보안성을 높이는데 베어러 토큰 인증 처리를 위해 BearerTokenAuthneticationFilter 제공