-
학원 day96. Rest API기록 2023. 1. 18. 17:02
스프링부트 이니셜라이저 : 이클립스, 비주얼스튜디오, 인텔리제이 각각에서 스프링부트 이니셜라이저를 제공
라이브러리 의존성을 쉽게 관리할 수 있다. spring boot starter web, spring boot starter jpa.. 등의 라이브러리 의존성을 지원해준다. 해당 라이브러리의 하위 의존성들이 자동으로 어플리케이션에 포함되게 된다.
스프링부트는 다양한 형태로 패키징이 가능하다. jar 또는 war
JSP를 템플릿 엔진으로 사용하는 spring boot 웹 어플리케이션
- 패키징 방식 : war
- JSP를 지원하는 내장형 톰캣과 JSTL 태그 라이브러리를 추가
패키징방식을 war라고 해야한다.
war : Web Application Archive
jar : Java Archive
모두 JAVA의 jar 툴을 이용하여 생성된 압축(아카이브) 파일이며 어플리케이션을 쉽게 배포하고 동작시킬 수 있도록 있도록 관련 파일(리소스, 속성파일 등)들을 패키징해주는 것이 주 역할이다.
(출처 및 참고사이트 : https://ifuwanna.tistory.com/224, https://try-it.tistory.com/10)
mybatis 또는 jpa 또는 hibernate 등 다양한 db엑세스 기술하고 연동해서 dao를 구현할 수 있다.
Spring Data를 활용해서 db엑세스를 편하게 할 수 있다.
Spring boot REST API 애플리케이션
컨트롤러를 만들때 @RestController라는 어노테이션을 붙여서 만든다. 별도의 뷰가 필요없다.
Rest API는 요청을 할 때에도 JSON 형식의 데이터를 내려받고, 응답을 보낼 때도 JSON 형식의 데이터를 응답으로 전해주는 것이다.
- 패키징 방식 : jar
- spring boot : 내장형 톰캣 사용
- 클라이언트와 서버가 json 데이터를 교환
- HTTP의 다양한 요청 방식을 사용한다.
GET/POST/PUT/DELETE 요청 방식을 사용
화면은 프론트엔드에 맡기고 백엔드는 데이터교환만 하는 것이다.
REST
- Representational State Transfer
- 자원을 이름으로 구분하여 해당 자원의 상태(정보)를 주고 받는 것
- HTTP의 URI을 통해 자원(Resource)을 명시하고, HTTP Method(POST, GET, PUT, DELETE)을 통해 해당 자원에 대한 CRUD 작업을 적용하는 것
- 자원에 대한 CRUD 작업
* Create : 생성(POST)
* Read : 조회(GET)
* Update : 수정(PUT)
* Delete : 삭제(DELETE)
REST의 필요성
- 애플리케이션의 분리(백엔드와 프론트엔드의 분리)
- 다양한 클라이언트의 등장
- 서버가 다양한 브라우저(javascript), 안드로이드, 아이폰과 같은 다양한 디바이스와 통신 지원
REST의 구성요소
- 자원(Resource) : URI
* 모든 자원(정보)에 대한 고유한 아이디가 존재한다.
* 자원을 구분하는 아이디는 '/users/{userId}'와 같은 URI다.
- 행위(Verb) : HTTP method
* HTTP method로 자원에 대한 CRUD operation을 정의한다.
- 표현(Representaion of Resource) : JSON, XML, TEXT, RSS
* 클라이언트가 자원에 대한 조작을 요청하면 서버는 적절한 응답(Representaion)을 제공한다.
* REST에서 하나의 자원은 JSON, XML, TEXT, RSS 형식으로 표현된다.
* JSON이나 XML로 주고받는 것이 일반적이다.
REST API(Application Programming Interface)
- API(Application Programming Interface)
* 데이터와 기능들의 집합을 제공한다.
* 컴퓨터 프로그램간 상호작용을 촉진하여, 서로 정보를 교환 가능하도록 한다.
- REST API
* Rest를 기반으로 서비스 API를 제공하는 것
* Open API(누구나 사용할 수 있는 공개된 API: 다음 지도 API, 다음 REST API, 공공 데이터 API)등이 REST API를 구현된 것이다.
REST API 설계 기본 규칙
- URI는 자원을 표현한다.
* 자원은 동사보다 명사, 대문자보다 소문자를 사용한다.
예시)
/Students/1 -> studients/1
* 자원의 document 이름은 단수형으로 표현한다.
* 자원의 collection이나 store는 복수형으로 표현한다.
- 자원에 대한 행위는 HTTP 메소드로 표현한다.
예시)
GET/students/delete/1 -> DELETE / students/1
POST/students/insert -> POST/students
- 경로의 / 는 계층관계를 나타낸다.
예시)
Get /teams/{teamId}
Get /teams/{teamId}/playes/{playerId}
- 파일의 확장자는 포함하지 않는다.
- 리소스(자원) 간에 연관관계가 있는 경우
/리소스/리소스 아이디(자원을 고유하게 식별할 수 있는 것)/관계가 있는 다른 리소스명
예시)
/user/{userId}/orders
- 필요한 경우 쿼리스트링으로 부가적인 정보를 포함할 수 있다.
모든 팀을 조회 GET /teams/
10개씩 팀을 조회 GET /teams?page=1
팀을 검색 GET /teams?opt=city&keyword=서울
특정팀의 모든 선수 조회 GET /teams/{teamId}/players
특정팀의 모든 선수를 이름순으로 정렬 조회 GET /teams/{teamId}/playes?sort=name
- REST API 설계 예시
원칙은 위와 같이 적는 것이지만 아래와 같은 방식으로 작성해도 상관없다.
@Data
: lombok에서 지원해주는 어노테이션으로, getter, setter, toString이 자동으로 만들어진다.
만약, Getter만 만들고 싶으면 @Getter라고 적어주면 된다.
UserResultMap은 실제로는 User객체가 만들어지게 하는 것인데, select문을 실행했을 때 얻어지는 컬럼을 한군데 매핑해두고 가져다쓰기 위해 만든것임.
private final UserMapper userMapper;
@Autowired
public UserService(UserMapper userMapper) {
this.userMapper = userMapper;
}
위와 같은 코드를 적으면 생성자 메소드를 통해 자동으로 주입받는 것임.
이같은 코드를 아래처럼 @RequiredArgsconstructor 라는 어노테이션을 활용해서 간단하게 적을 수 있다.
@PathVariable() : 경로에 있는 URL을 매핑시키는 것이다. () 괄호 안에는 {}에 있는 리소스 아이디랑 똑같이 적어주면 됨
@Controller과 @RestController
* @Controller 어노테이션이 지정된 컨트롤러 클래스의 요청핸들러 메소드가 JSON 형식의 데이터를 응답으로 제공하기 위해서는 @ResponseBody어노테이션을 메소드에 지정해야 한다.
* @RestController 어노테이션이 지정된 컨트롤러 클래스의 요청핸들러 메소드가 JSON 형식의 데이터를 응답으로 제공할때에는 @ResponseBody 어노테이션을 생략할 수 있다. (JSON이나 xml 응답데이터 보내는 전용이다.)
@Controller로는 jsp, 재요청URL, json 모두 가능하지만,
@RestController는 json밖에 못보낸다. jsp를 전달해줄 수 없다.
@RestController 안에 @ResponseBody가 들어있기 때문에 @ResponseBody는 안붙여도 된다.
@RequestBody는 요청메세지의 바디부에 xml, json형태의 데이터가 들어있을 때 사용한다.
Rest API를 만들 때 PostMan을 활용해서 프런트엔드를 대신할 수 있다.
Open API를 사용할 때 테스트해볼 수 있다.
POSTMAN에서 post로 선택하고, http://localhost/users라고 적는다.
요청메세지의 Body에 들어갈 부분이기 때문에 Body 체크, raw체크
JSON에서 텍스트는 꼭 ""쌍따옴표 사이에 들어가 있어야 한다.
POSTMAN에서 send를 클릭하면 아래와 같이 userRegisterForm안에 값이 들어가있음을 확인할 수 있다.
@RequestBody가 적혀있기 때문에 값이 그대로 들어가 있음을 확인할 수 있다.
CORS 보안
브라우저는 http://localhost:8080/web-admin/user.html이라는 url을 호출해서 사용자목록 페이지를 불러온다. 즉, 페이지의 출처는 origin:http://localhost:8080이다. 그런데 사용자목록 데이터는 http://localhost:80(80은 생략가능)에 ajax로 요청한다. ajax요청인 경우에는 ajax를 요청하는 페이지와 ajax요청을 처리하는 곳의 출처가 동일해야 한다.
ajax를 요청하면, 이 화면의 출처가 어딘지도 전달된다.
그런데 이 화면의 출처가 자기가 아니라 다른 웹서버이기 때문에 ajax요청처리를 거부한다.
그런데 거부안하게 해야 하니까 UserController에 @RestController 밑에 @CrossOrigin("*")을 붙인다.
@CrossOrigin(origins = "http://localhost:8080") 이라고 적으면 8080인 곳에서 가져갈 수 있는 것이다.
CORS 가 교차출처리소스공유라는 것이다. (브라우저에서는 보안적인 이유로 cross-origin HTTP 요청들을 제한한다. 그래서 cross-origin 요청을 하려면 서버의 동의가 필요)
(출처 : https://hannut91.github.io/blogs/infra/cors )
Rest API 어플리케이션은 어떤 프런트엔드 애플리케이션이든 상관없이 데이터만 제공해주는 것임.
$.getJSON(url, data, function(response) { ... });
* url은 ajax 요청을 처리하는 요청 URI다.
* data는 서버로 보내는 데이터, 생략가능하다.
* function(response) { ... }는 서버로부터 성공적인 응답이 왔을 때 실행되는 함수다.
* response에는 서버가 보낸 응답데이터가 들어있다.
* response로 전달된 데이터는 json 형식의 텍스트를 자바스크립트 객체/배열로 변환한 것이다.
* 응답데이터가 [] 구조일 때-> 자바스크립트 배열
* 응답데이터가 {} 구조일 때-> 자바스크립트 객체
* 위의 예제는 사용자 목록을 응답데이터로 받는다.
응답데이터 : jsonText -> '[{"id":"hong", "name":"김유신"}, {"id":"kang", "name":"강감찬"}]'
users : 자바스크립트 배열 -> [{id:"hong", name:"김유신"}, {id:"kang", name:"강감찬"}]
users.forEach(function(user, index) { ... })
* users는 배열객체다.
* 배열객체는 forEach(함수) 메소드를 가지고 있다.
* 배열객체의 forEach(함수) 메소드는 배열이 가지고 있는 데이터의 갯수만큼 함수를 실행시킨다.
* 함수 -> function(value, index) { ... }
* value에는 함수가 실행될 때 마다 배열의 0번째부터 마지막번째 데이터가 하나씩 전달된다.
* index에는 함수가 실행될 때 마다 배열의 index 값이 하나씩 전달된다.(0부터 시작하는 값)
* user에는 {id:"hong", name:"김유신", createdDate:"2023.1.12"}가 전달된다.
* 함수의 내부에서는 user.id로 아이디를, user.name으로 이름을, user.createdDate로 가입일을 조회할 수 있다.'기록' 카테고리의 다른 글
학원 day98. Spring Security (0) 2023.01.20 학원 day 97. ajax, each함수 (0) 2023.01.19 학원 day95. @SessionAttributes, 스프링부트 (0) 2023.01.17 학원 day94. Ajax요청 처리, 자바스크립트 배열 (0) 2023.01.16 학원 day93. View를 이용한 파일 다운로드 (0) 2023.01.13