2021년 7월 추가
처음 이 강의를 들었을 때는 스프링부트를 한번도 써본 적이 없는 상태였기 때문에 강의 내용이 다소 추상적으로 다가왔다.
현재 수준은 스프링부트 게시판 튜토리얼을 이해하고 응용할 수 있는 정도다. 다시 읽어보니 진행중인 프로젝트에 이 강의의 내용이 아주 유용하게 쓰일 것 같다.
2021년 2월, Steve(예상국)님의 'Kotlin으로 개발하는 Spring Boot Web MVC' 강의를 듣고 정리한 글입니다.
Spring Boot Framework
- Build Tool: Gradle
- Servlet Containers: Tomcat
Spring Boot의 장점
- 앱 개발의 필수 요소만 모았다.
- 간단한 설정으로 개발 및 커스텀이 가능하다.
- 간단하고, 빠르게 앱 실행 및 배포가 가능하다.
- 대규모 운영환경에 필요한 비 기능적 기능(보안, 모니터링 등)도 제공한다.
- 오랜 경험에서 나오는 안정적인 운영이 가능하다.
- Spring에서 불편한 XML 설정 등이 없어졌다.
Web 개론
Web: World Wide Web. 인터넷에 연결된 컴퓨터를 통해 사람들이 정보를 공유하는 공간
Web의 용도
- Web Site: Google, Naver ...
- User Interface: Chrome, IPTV, Smart Watch ...
- API(Application Programming Interface) *Web Service:Kakao Open API, Google Open API ...
Web의 기반
- URI(Uniform Resource Identifier): 리소스 식별자
- HTTP(Hypertext Transfer Protocol): 앱 컨트롤. GET, POST, PUT, DELETE, OPTIONS, HEAD, TRACE, CONNECT의 Method가 존재
- HTML(Hyper Text Markup Language): XML을 바탕으로 한 범용 문서 포맷. 이를 이용해 웹 브라우저에서 사용자가 알아보기 쉬운 형태로 표현.
REST(Representational State Transfer): 자원의 상태 전달. 네트워크 아키텍처 원리.
- Client, Server: 클라이언트와 서버가 독립 분리
- Stateless: 요청에 대해 서버에 클라이언트의 상태를 저장하지 않음
- Cache: 클라이언트는 서버의 응답을 캐시할 수 있어야 한다. 캐시를 통해 클라이언트는 응답을 재사용한다. 이를 통해 서버의 부하를 낮춘다.
- 계층화(Layered System): 서버와 클라이언트 사이에 방화벽, 게이트웨이, Proxy 등 다계층 형태를 구성하고 확장할 수 있어야 한다.
- 인터페이스 일관성: 아키텍처를 단순화하고 작은 단위로 분리해서 클라이언트, 서버가 독립적으로 개선될 수 있어야 한다.
- Code On Demand(Optional): 자바 애플릿, 자바스크립트 플래시 등 특정 기능을 서버가 클라이언트에 코드를 전달해 실행할 수 있어야 한다.
인터페이스의 일관성
REST 를 잘 지켰는지 판단하는 기준.
- 자원식별: URI 형식으로 자원과 식별자를 표현한다.
e.g. https://foo.co.kr/user/100
Resource: user
identifier: 100
- 메시지를 통한 리소스 조작: Header에 content-type을 통해서 리소스의 타입을 지정
- 자기서술적 메시지: 요청하는 데이터의 처리 방법에 대한 충분한 데이터를 포함해야 한다. HTTP 기반의 REST에서는 HTTP Method와 Header의 정보로 표현한다.
- 애플리케이션 상태에 대한 엔진으로서 하이퍼미디어를 제공해야 한다: REST API를 개발할 때에도 단순히 클라이언트 요청에 대한 데이터만 주는 것이 아니라 관련된 리소스에 대한 Link 정보까지 같이 포함돼야 한다.
이 조건을 잘 갖추면 RESTful하다고 평가한다. 이를 REST API라고 한다.
URI 설계 방법
URL은 URI의 하위 개념이다.
- URI: 인터넷에서 특정 자원을 나타내는 주소값이다. 해당 값은 유일해야 한다.
ex: https://www.foo.co.kr/resource/sample/1
response: sasmple1.pdf, sample2.pdf, sample.doc ..
- URL(Uniform Resource Locator): 인터넷 상에서의 특정 자원의 위치를 식별하는 주소
URI 설계원칙(RFC-3986)
URI Query Parameter 디자인
HTTP
- RFC2616에서 규정된 웹에서 데이터를 주고 받는 프로토콜
- 이름은 하이퍼 텍스트 전송용 프로토콜이지만 실제로는 HTML, XML, JSON, Image, Voice, Video, Javascript, PDF 등 컴퓨터에서 다룰 수 있는 여러 정보를 모두 전송할 수 있다.
- TCP를 기반으로 한 REST의 특징을 모두 구현하는 WEB 기반 프로토콜
- HTTP는 메시지를 주고(Request) 받는(Response) 통신 방식이다. 하나의 요청이 있으면 하나의 응답이 따라오는 형식이다.
- RequestTimeOut: 요청이 있었으나 서버가 응답을 하지 않았을 때
- ResponseTimeOut: 요청이 있었으나 서버가 원하는 시간 내에 응답하지 않아서 연결을 끊었을 때
등등.. 백엔드 개발자가 이 점을 유념해 코드를 작성해야 한다.
HTTP의 8가지 메소드
- GET: 자원 취득. CRUD에서 Read. 몇번을 요청해도 같은 결과를 준다(멱등성). API 호출 시 자원에 변화를 일으키지 않는다(안정성). URI Pattern에 Path Variable, Query Parameter 모두 사용한다. DataBody는 없다.
- POST: 자원 생성, 추가. CRUD에서 Create. 요청할 때마다 결과가 바뀐다(비멱등성) . API 호출 시 자원에 변화를 일으킨다(비안정성). URI Pattern에 Path Variable 사용한다. Query Parameter 사용할 수는 있지만 사용하진 않는다. DataBody 있다.
- PUT: 자원 갱신, 갱신할 데이터 없으면 생성. CRUD에서 Create, Update. Steve->steve로 변경 요청하는 사례를 들면, 몇번을 요청해도 결과는 동일하다(멱등성) . API 호출 시 자원에 변화를 일으킨다(비안정성). URI Pattern에 Path Variable 사용한다. Query Parameter 사용할 수는 있지만 사용하진 않는다. DataBody 있다.
- DELETE: 자원 삭제. CRUD에서 DELETE. 서버에 Steve란 데이터를 삭제하는 요청을 보낸다고 가정하자. 몇번을 요청해도 Steve 데이터가 없다라는 결과는 동일하다. (멱등성) . API 호출 시 자원에 변화를 일으킨다(비안정성). URI Pattern에 Path Variable, Query Parameter 사용한다. DataBody 없다.
HTTP 응답의 상태를 나타내는 코드
- 1XX: 처리중. 클라이언트는 요청을 계속하거나 서버의 지시에 따라서 재요청.
- 2XX: 성공.
- 3XX: 리다이렉트. Response의 새로운 주소로 다시 요청.
- 4XX: 클라이언트 에러. 재전송해도 에러가 해결되지 않는다.
- 5XX: 서버 에러. 재전송하면 에러가 해결될 수도 있다.
자주 사용되는 HTTP Status Code
- 200: 성공
- 201: POST, PUT 요청 시 리소스 생성 성공.
- 301: 리다이렉트, 리소스가 다른 장소로 변경됨을 알림
- 303: 리다이렉트, 클라이언트에서 자동으로 새로운 리소스로 요청 처리
- 400: 요청 오류, 파라미터 에러
- 401: 권한 없음(인증 실패)
- 404: 리소스 없음(페이지를 찾을 수 없음)
- 500: 서버 내부 에러(서버 동작 처리 에러)
- 503: 서비스 정지(점검 등)
REST API CRUD
GET
-
@GetMapping: GET Resource 설정
-
@RequestParam: URL Query Param Parsing
-
@PathVariable: URL Path Variable Parsing
-
Object: Query Param Object 로 Parsing
-
Map: Map으로 Parsing
POST
-
@PostMapping: Post Resource 설정
-
@RequestBody: Request Body 부분 Parsing
-
@PathVariable: URL Path Variable Parsing
잘 사용하지는 않는다.
PUT
-
@PutMapping: Put Resource 설정
-
@RequestBody: Request Body 부분 Parsing
-
@PathVariable: URL Path Variable Parsing
DELETE
-
@DeleteMapping: Delete Resource 설정
-
@RequestParam: URL Query Param Parsing
-
@PathVariable: URL Path Variable Parsing
-
Object: Query Param Object로 Parsing
REST API Response 관리하기
응답을 내리는 방법은 여러 가지가 있지만, 가장 추천하는 방법은 @ResponseEntity를 통해 Status Code를 조작하는 방식이다.
@Controller, @RestContoller Annotation을 섞어 쓰는 것은 권장하지 않는다.
Page는 PageContoller에서 관리하고, Rest API는 @RestController로 따로 관리하는 것을 권장한다.
- String: Plain Text Type Response
- Object: 자동으로 Json 변환돼 응답. HttpStatus Code 항상 200 OK. HttpStatus Code을 조작하고 싶으면 어떻게 바꾸지?
- ResponseEntity: HttpStatus Code 조작 가능. Body의 내용을 Object로 설정.
- @ResponseBody: 우리는 REST API를 사용해서 이건 사용 안할 확률이 높다. RestController가 아닌 곳(Controller)에서는 return값에 해당하는 HTML Page를 찾아 return한다. 그런데 return 값으로 HTML Page가 아닌 Json 응답을 주고 싶으면 @ResponseBody를 붙인다.
Spring Boot Validation
Validation을 사용하는 이유?
-
유효성 검증하는 코드의 길이가 너무 길다
-
Service Logic에 대해서 방해가 된다
-
흩어져 있는 경우 어디서 검증됐는지 찾기 힘들다
-
검증 로직이 변경되는 경우 테스트 코드 등 전체 로직이 흔들릴 수 있다.
spring-boot-starter-validation
-
@Size : 문자 길이 측정. Int Type 불가
-
@NotNull: null 불가
-
@NotEmpty: null, "" 불가
-
@NotBlank: null, "", " " 불가
-
@Past: 과거 날짜
-
@PastOrPresent: 오늘이거나 과거 날짜
-
@Future: 미래 날짜
-
@FutureOrPresent: 오늘이거나 미래 날짜
-
@Pattern: 정규식 적용
-
@Max: 최대값
-
@Min: 최소값
-
@AssertTrue @AssertFalse: 별도 Logic 적용
-
@Valid: 해당 object Validation 실행
강의에서 사용된 검증 함수들
Validator
Custom Validation
Custom Validation Annotation
계속해서 사용되는 패턴에 대해서는 메소드를 만들기보다는, 따로 어노테이션을 만들어 관리하는 편이 편리하다.
-
StringDateTimeFormat
-
Annotation
-
ConstraintValidator
-
isValid
Talend API
Chrome Web Extension
Download Link
Swagger
URL: http://localhost:PORT/swagger-ui
Frequently Used Annotations
-
Api: 클래스를 스웨거 리소스로 표시
-
ApiModel: 스웨거 모델의 추가 정보 제공
-
ApiModelProperty: 모델 속성의 데이터를 추가하고 조작
-
ApiOperation: 특정 경로의 오퍼레이션이나 HTTP Method 설명
-
ApiParam: Operation Parameter에 추가 Meta Data 추가
-
ApiResponse: Operation Response 예를 설명
-
ApiResponses: 여러 ApiResponse 객체 리스트를 허용하는 객체
-
Authorization: 리소스나 오퍼레이션에 사용되는 권한 부여체계
-
AuthorizationScope: Oauth2 인증 범위를 설명
-
ResponseHeader: 응답의 일부로 제공될 수 있는 헤더를 표시
출처
인프런 - Steve(예상국), Kotlin으로 개발하는 Spring Boot Web MVC