스프링 RESTful API - HiroSung/Study GitHub Wiki
1. 스프링과 스프링 부트 소개
1.1 Spring & Spring Boot
1.1.1 스프링 프레임워크
- 정의
- java 엔터프라이즈 개발을 편하게 해주는 오픈소스 경량급 애플리케이션 프레임워크.
- 특징
- 컨테이너 역할
- Spring 컨테이너는 java lifecycle 관리.
- DI 지원
- 설정 파일이나 어노테이션을 통해서 객체 간의 의존관계를 설정할 수 있도록 하고 있음.
- AOP 지원
- POJO 지원
- 트랜잭션 처리를 위한 일관된 방법을 지원
- JDBC, JTA
- 영속성과 관련된 다양한 API 지원
- 컨테이너 역할
1.1.2 스프링과 메이븐
- 메이븐은 빌드 툴
- 개발 환경
JDK 설치 : https://www.oracle.com/java/technologies/javase/jdk12-archive-downloads.html Intelij 설치 : https://www.jetbrains.com/ko-kr
1.2 Spring Boot
1.2.1 차세대 스프링 프레임워크
- 스프링 기반 production-ready 어플리케이션 개발
- Convention over Configuration : 내가 필요한 부분만 설정하여 사용하겠다. 설정을 미리 함.
- 톰캣이 내장되어 단독으로 실행 가능
- 설정을 최대한 줄이고 xml 설정 파일 필요 없음.
1.2.2 시작하기
- http://start.spring.io 에서 설정하여 초기 설정 파일 다운 받기
- 다운받아 압축을 풀면 pom.xml 파일을 사용함.
- 스케폴딩 기능을 이용하여 기본설정으로 프로젝트를 만들 수 있음.
- InteliJ - Import > pom.xml 파일이 있는 폴더를 선택하고 시작.
- Spring Boot CLI
1.3 실습 : 첫 번째 엔드 포인트
- SOA : 서비스들을 조합하여 웹서비스형태로 사용함.
- Web Service : 서비스 지향적 분산 컴퓨팅 기술의 일종으로 SOAP, WSDL, UDDI 등의 형태로 구성됨.
- RESTful Web Service
- End Point : 서비스를 이용할 수 있는 주소. http URI 로 되어 있음.
1.3.1 End Point 란?
- 서비스를 이용할 수 있는 주소
- 오픈 API 주소
- API는 머신이, 웹사이트는 사람이 사용하는 것임.
2. REST와 Resource 이해
2.1 툴
- RestFul API 테스트 툴 : PostMan
2.2 웹 서비스
- 두 엔드포인트간 메시지 전달 방식
- IoT의 증가로 API 필요성 증가
- Use Cases : 과금 가능
2.3 REST 원리 및 원칙(제약조건)
- Client-Server 기반
- HTTP 전송규약 사용
- Stateless
- 그전에는 statefull (상태가 있도록) 하게 개발하였음. 그래서 Cache를 사용할 수 없음.
- REST는 Cache를 사용할 수 있음.
- 세션정보와 같은 context를 저장할 필요가 없음.
- 클라이언트는 자신을 구분하기 위해 서버에게 충분한 정보를 전달해야 함. (API Key 또는 Token)
- Cacheable
- 입력이 같으면 출력이 같다고 보장하기에 HTTP 프로토콜의 Caching 기능을 적용할 수 있음
- 구현은 Last-Modified 나 E-Tag 사용.
- 성능 향상 가져옴.
- 단점은 매번 세션을 체크 해야 하므로 서버 성능 요구됨.
- Layered System
- 시스템 스캐일링을 위해서 Gateway, Proxy Server, Firewall 과 같은 또 다른 Layer들을 수용함.
- 여러개의 모듈이 인점한 서비스 간에만 통신을 하도록 함.
- **Representation **of Resouces
- URI 와 리소스가 매핑되됨
- 구현의 자유
- 다양한 방식으로 구현될 수 있는 아키텍처 스타일
2.4 HTTP
2.4.1 컨텐트 타입
2.4.2 Http Methods
- GET / POST / HEAD / TRACE ...
2.4.3 Status Code
- 성공 : 2**
- 에러 : 4** (Client), 5**(Server)
- 리다이렉트 : 3**
2.4.4 URI
- 파라미터가지 포함된 정보
- EndPoint라고 하면 URI를 말함.
2.4.5 데이터는 왕
- 소프트웨어는 대체되어도 수년간 쌓인 데이터는 대체할 수 없음
- SOAP : 동작과 프로세싱에 집중
- REST : 데이터에 집중
- 서버가 보내준 데이터는 Resource가 아니라 Representation(표현) 이다.
- RESTFul 기반 웹 서비스 : HTTP 기반으로 데이터를 처리 하는 서비스
- SOAT vs REST
- SOAP : 많은 어플리케이션에게 부담
2.5 REST ?
- 2000년 HTTP프로토콜저자 Roy Fiolding 박사가 소개
2.6 Uniform Interface
- Resource-Based
- URI는 명사 형태로 정의
- Representation으로 리소스 처리
- Content Negotiation
- Self-Descriptive message & API
- REST는 Stateless 하기 때문에 클라이언트-서버간 충분한 설명적인 메시지가 필요 : http method, http state code, http hedder
- HATEOAS (헤이터스)
- RESTful API 최고 레벨
- 하나의 URL에 여러개의 수행이 가능하도록 사용하기 위한 서비스
- 클라이언트가 서버에 요청시 서버는 요청에 의존되는 URI를 Response에 포함시켜 반환한다.
3. Layered Architecture
- 프리젠테이션 영역
- Controller
- 비지니스 영역
- 기능. 트랜잭션 수행
- 데이터 영역
- Persistence(영구저장) Layer
4. RESTful API 패턴
4.1 REST 요청/응답 패턴
- URI(EndPoint)로 Client에서 Header정보를 넣고 요청.
- 서버에서 Spring에서 자동으로 생성해줌.
4.2 Content negotiation
4.2.1 다른 방식 두가지
- 리소스 URI의 확장자를 사용하는 방식
https://xxx.api.com/v1/students/course.xml
- 파라미터를 활용하는 방식
https://xxx.api.com/v1/students/course?format=xml
4.2.2 기타
- 클라이언트 우선순위 : Accept: , ...;q=0.9, /;0=0.8
- 압축 지원
- Request : Accept-Encoding: gzip
- Response : Content-Encoding : gzip Vary: Accept-Encoding
- 협상 실패시
- Accept: application/json, /;q=0.0 (JSON이외는 처리 않겠다)
- 서버는 406 Not Acceptable 전송
4.2 URI 템플리트
- @PathVariable
- @RequestParam
- ...
4.3 Pagination , 페이징 처리
- 옵셋기반
- 페이지 넘버와 개수를 기반으로 함
- 시간기반
- 특정 시간을 기반으로 함
- 주로 시계열 데이터에서 사용 가능
- 커서기반
- 데이터 접근 커서를 기반
GET slack.com/api/users.list?limit=2&tocken=xoxp-1234-5678-0922
4.4 Unicode
- 다국적 문자 세트를 지원하는 엔코딩 표준
5. REST에서 CRUD 구현 : URI 설계
5.1 UserController 생성 /users
- GET | POST | PUT | DELETE
- POST / PUT은 body 수행 가능
- 설계
- 전체보기 : GET /users
- 상세보기 : GET /users/{userId}
- 회원가입 : POST /users
- 상세수정 : PUT /users/{userId}
- 회원삭제 : DELETE /users/{userId}
5.2 DTO 디자인 패턴
- 데이터를 각 서버/클라이언트 간 전달하기 위한 목적으로 만든 객체
- java.io.Serializable 인터페이스 구현 - 객체 직렬화 지원
- Immutable 객체로 만듬 - Setter 포함하지 않음.
- src > main > java > kr.re.kitri.hello > domain 아래에 명사로 대부분 정의함
5.3 JSON
- Client로 전송될때 객체로 전송되게 됨.
- JSON (JavaScript Object Notation)은 경량의 DATA-교환 형식 이다.
6. REST 서비스 디자인 패턴
- 6.1 API Versioning
- 6.2 Uniform contract
- 6.3 Entity Endpoint
- 6.4 Endpoint redirection
- 6.5 응답코드와 REST 패턴
6.1 API Versioning
6.1.1 버전 넘버
- Major.Minor(V1.1) 또는 Major 만 사용 (v1)
- 시멘틱 버져닝은 MAJOR.MINOR.PATCH 같은 3자리 형식으로 사용
6.1.2 세가지 방식
- URI경로에 버전정보 포함
http://api.foo.com/coffees/1234 http://api.foo.com/v2/coffees/1234
- 요청쿼리 파라미터에 버전정보 파함
- 헤더에 포함
Accept: application/vnd.git.hub.v3+json
- Accept 헤더 사용 (content-negotiation)
- x-resource-version 같은 커스텀 헤더도 가능
6.2 Uniform contract
- 일관된 주소 경로
- API 서비스는 계혹해서 수정, 발전, 버그픽스, 보안패치 등 변화함.
- REST 원칙 상 엔드포인트는 HTTP verbs 만 사용해야 함.
- GET / POST / PUT / PATCH / DELETE
- PATCH : 기존것과 구분을 두기 위해서 사용
6.3 Entity Endpoint
- 엔티티 : 관계형에서는 테이블
6.4 Endpoint redirection
- HTTP Status가 301이면 Location 을 찾아서 이동해라는 것임. 웹브라우저는 구현되어 동작되고 있음
- 엔드포인트 변경 시 클라이언트에게 통보 하는 방법
- HATEOAS 구현 사용
6.5 응답코드와 REST 패턴
6.5.1 표준응답코드
- 200번대 : 응답성공
- 비동기 : broker 와 같은 중간 체크자가 있어야 함. Queue와 같은 역할. (RabbitMQ, Kafka)
- 동기 : thread로 처리 하지만, thread가 여러개로 해서 multi-thread 방식으로 구성 가능.
- 향후는 대부분 비동기 처리로 구성이 될것임.
- 202 Accepted : 비동기 작업에서 사용됨, 아직 동작이 완료되지 않았음. Location헤더를 반환해야 하며, 요청을 모니터링 할 수 있음.
- 300번대 : 리다이렉션
- 400번대 : 클라이언트 요청 에러
- 401 Unauthorized : 인증이 되지 않아 응답이 거부됨
- 404 Not Found: 요청한 리소스가 잘못. 인가 문제
- 406 Not Acceptable : Accept 헤더에 대한 응답이 없을때
- 415 Unsuported Media Type
- 500번대 : 서버 에러
6.5.2 사례
6.5.3 오류코드
@ResponseStatus(403)
7. 보안과 추적성
7.1 REST API 로깅
- 복잡한 분산 어플리케이션은 에러가 발생할 포인트로 다양
- 분산된 어플리케이션으로 부터 로그를 모으고 분석 필요 예) Splunk
- Servlet Filter 를 이용한 로깅
@WebFilter Filter(filterName = "LoggingFilter", urlPatterns = {"/*"})
public class LoggingFilter implements Filter {
static final Logger logger = Logger.getLogger(LoggingFilter.class);
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
logger.info("request" + httpServletRequest.getPathInfo().toString());
filterChain.doFilter(servletRequest, servletResponse);
}
}
- Servlet 처리 전에 Filter가 체크함.
- Filter는 Layering 처리 할 수 있음.
- Spring의 Filter는 Interceptor 이다.
- Filter vs Interceptor
- Spring Security도 Filter이다.
7.2 Spring boot logging System
- Logback 기본으로 설정되어 있음. 성능이 좋음.
- 로깅레벨 : TRACE / DEBUG / INFO / WARN / ERROR
- Logger 사용
- org.slf4j 의 Logger 를 사용하면 표준 I/F로 로깅처리 할 수 있음.
package com.example.restapp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
!// other imports
@RestController
public class HomeController {
private static final Logger logger =
LoggerFactory.getLogger(HomeController.class);
@GetMapping(“/“)
public Map<String, Object> test() {
Map<String, Object> map = new HashMap!<>();
map.put("result", "Aloha");
logger.trace("{test} trace");
logger.debug("{test} debug");
logger.info("{test} info");
logger.warn("{test} warn ");
logger.error("{test} error");
return map;
}
8. 예외처리
8.1 Spring 예외처리 방법
- 전역처리 Global Level - @ControllerAdvice
- 예외처리를 한곳에 정의 해서 처리함.
- 컨트롤러단에서 처리 Controller Level - @ExceptionHandler
- 메소드 단위처리 Method level - try/catch
- 비지니스 예외 처리
- sub system 당 1개의 런타임을 발생하도록 함.
9. 인증과 인가
9.1 인증방식의 변화
- 과거는 SSO를 사용. SOA 기반 아키텍처는 적함하지 않음.
10. Spring Security and JWT
- Token 방식의 인증이 일반적이고, OAuth 방식도 있음.
- JWT Json Web Token
- Token 생성방식이 다양해서, 표준화하여 생성화 한것.
10.1 Spring Security
- 인증과 권한 F/W
10.2 주요 인증 방식
- 로그인 기반 인증
- 2단계 인증
- 하드웨어 인증
10.3 서버기반 인증 문제점
- 세션처리로 동접자가 많으면 서버에 무리 발생
- ID/PWD(크레덴션 기반인증) 로 로그인하여 인증 후, 서버 메모리 공간에 저장함. 쿠키정보로 클라이언트로 내려보냄
- 확장성이 복잡해짐
- EHCache, MamChached ...
- CORS (Cross-Origin Resource Sharing)
- 쿠키를 여러 도메인에서 관리 하는 것이 번거로움
10.4 토큰기반 인증
- Stateless이고 Scalability 함.
- 보안성
- Extensibility
- 여러 플래폼 및 도메인 : CORS
- 웹 표준 기반
- JWT - 토큰기반 인증 시스템 구현체
10.5 JWT
- JWT 소개 사이트
- JWT 구조
- 헤더.내용.서명
- 토큰 만들기
- 디펜던시 설정
11. 테스트
- JUnit 테스트
- MockMvc (Controller mocking)
교육정보
- 교육명 : Spring RESTful API Service 개발
- 강의SRC: https://github.com/soongon/restapp\
- 교재안 : 교재안 Restful API
- 장소/기간 : KITRI / 2020.05.06~08
- 강사 : 김순곤 / [email protected]