본문 바로가기

Backend/Spring

5. STS / REST API

REST(Representational State Transfer): 로이 필딩(Roy Fielding)의 2000년 박사학위 논문에서 소개된 용어로 "웹에 존재하는 모든 자원(이미지, 동영상, DB 자원)에 고유한 URI를 부여해 활용"하는 것으로, 자원을 정의하고 자원에 대한 주소를 지정하는 방법론을 의미한다고 한다.

 

Restful API: REST 특징을 지키면서 API를 제공하는 것을 의미한다. HTTP 통신에서 어떤 자원에 대한 CRUD 요청을 Resource와 Method로 표현하여 특정한 형태로 전달할지 정해주는 가이드라인

 

 

REST 의 주요한 목표

1. 구성 요소 상호작용의 규모 확장성(scalability of component interactions)
2. 인터페이스의 범용성 (Generality of interfaces)
3. 구성 요소의 독립적인 배포(Independent deployment of components)

4. 중간적 구성요소를 이용해 응답 지연 감소, 보안을 강화, 레거시 시스템을 인캡슐레이션 (Intermediary components to reduce latency, enforce security and encapsulate legacy systems)

 

REST 아키텍처에 적용되는 6가지 제한 조건
다음 제한 조건을 준수하는 한 개별 컴포넌트는 자유롭게 구현할 수 있다.


1.  클라이언트/서버 구조: 일관적인 인터페이스로 분리되어야 한다

2.  무상태(Stateless): 각 요청 간 클라이언트의 콘텍스트가 서버에 저장되어서는 안 된다
3.  캐시 처리 가능(Cacheable): WWW에서와 같이 클라이언트는 응답을 캐싱할 수 있어야 한다.
     잘 관리되는 캐싱은 클라이언트-서버 간 상호작용을 부분적으로 또는 완전하게 제거하여 scalability와 성능을 향상시킨다.
4.  계층화(Layered System): 클라이언트는 보통 대상 서버에 직접 연결되었는지, 또는 중간 서버를 통해 연결되었는지를 알 수 없다. 중간 서버는 로드 밸런싱 기능이나 공유 캐시 기능을 제공함으로써 시스템 규모 확장성을 향상시키는 데 유용하다.

5.  Code on demand (optional) - 자바 애플릿이나 자바스크립트의 제공을 통해 서버가 클라이언트가 실행시킬 수 있는 로직을 전송하여 기능을 확장시킬 수 있다.
6.  인터페이스 일관성: 아키텍처를 단순화시키고 작은 단위로 분리(decouple)함으로써 클라이언트-서버의 각 파트가 독립적으로 개선될 수 있도록 해준다.

 

RESTful API 설계

1. URI는 정보의 자원을 표현해야 한다.(리소스명은 동사보다는 명사를 사용)

2. 자원에 대한 행위는 HTTP Method(GET, POST, PUT, DELETE 등)으로 표현

 

URI 설계시 주의할 점

1. 슬래시 구분자(/)는 계층 관계를 나타내는데 사용

2. URI 마지막 문자로 슬래시(/)를 포함하지 않는다.

3. 하이픈(-)은 URI 가독성을 높이는데 사용

4. 밑줄(_)은 URI에 사용하지 않는다.

5. URI 경로에는 소문자가 적합하다.

6. 파일확장자는 URI에 포함하지 않는다.

 

*출처: 

brainbackdoor.tistory.com/53

ko.wikipedia.org/wiki/REST

 

 

 

STS 에서 RESTful 방식 사용하기 전 알아야 될 것들

1. @RestController 

  1) REST방식의 Controller 이다.

  2) 메소드의 리턴이 뷰가 아닌 "값"이다. ->기본적인 방식: Ajax

    -> @ResponseBody 애너테이션이 없어도 그 방식으로 동작한다.

  3) 리턴하는 데이터의 타입을 produces 속성에서 작성한다.

 

2. @ResponseBody 

 1) Bean(Dto) 데이터를 직접 만들어 -> JSON/XML로 변환해서 전송한다. (Controller -> 요청 JSP)

 2) 변환은 jackson 라이브러리가 담당한다.

 

3. @RequestBody

 1) JSON/XML -> Bean(Dto) 변환해서 전송한다. (요청 JSP -> Controller)

 2) ajax contentType 의 작성이 필요하다.

 

*추가*

Jackson Library: api 방식에서 주로 사용하는 JSON 데이터구조를 처리해주는 라이브러리. 

이 라이브러리 없이 json으로 처리를 해주기위해선 java에서 인스턴스를 사용해 필드 메소드를 만들고, jsonObject를 이용했다.

 

Jackson 에서 JSON 처리에 제공하는 방법
1. Streaming API
     성능이 빠름.
2. Tree Model
     일반적인 XML처럼 노드형태로 Json 데이터를 다룸. 유연성이 가장 좋음. 입맛대로 구성할 수 있음.
3. Data Binding
     POJO 기반의 가자 객체들을 JSON으로 변환함.
   -Simple data Binding : 자바클래스 내의 Map, List, String, 숫자형, Boolean, null 형의 데이터들을 JSON으로 변환함.
   -Full data binding : Simple data Binding에서 제공하는것들을 포함하고 자바 빈타입에서 제공하는 데이터들도 JSON으로 변환함.

*출처: https://arisu1000.tistory.com/27710

 

 

 

REST API 방식을 이용하여 간단한 유저정보(이름과 나이)를 불러오기

 

 

1. pom.xml 

<dependency>

    <groupId>org.projectlombok</groupId>

    <artifactId>lombok</artifactId>

    <version>1.18.12</version>

    <scope>provided</scope>

</dependency>

 

<dependency>

    <groupId>com.fasterxml.jackson.core</groupId>

    <artifactId>jackson-databind</artifactId>

    <version>2.11.0</version>

</dependency>

 

<dependency>

    <groupId>com.fasterxml.jackson.dataformat</groupId>

    <artifactId>jackson-dataformat-xml</artifactId>

    <version>2.11.0</version>

</dependency>

 

2. Dto

롬복을 사용하였기 때문에 Data, noArgs, allArgs 애너테이션으로 게터세터(Data), 인자 없는 생성자 생성(noArgs), 모든 인자를 가진 생성자(allArgs) 생성한다.

 

@Data

@NoArgsConstructor

@AllArgsConstructor

public class UserDto {

 

private String name;

private int age;

 

3. index.jsp

4가지 방법

(text, json, jsonList, sendJson)

 

// 페이지로드 이벤트 먼저 넣어주고

$(document).ready(function(){

$('#btn1').click(fn_getText);

$('#btn2').click(fn_getJSON);

$('#btn3').click(fn_getJSONList);

$('#btn4').click(fn_sendJSON);

 

 

function fn_getText() {

$.ajax({

url: 'getText',

type: 'get',

dataType: 'text',

success: function(responseText) {

$('#content1').text(responseText);

},

error: function() {

alert('실패');

}

});

}

 

function fn_getJSON() {

$.ajax({

url: 'getJSON',

type: 'get',

dataType: 'json',

success: function( obj ) {

$('#content2').text(obj['name']+','+obj.age);

},

error: function() {

alert('실패');

}

});

}

 

function fn_getJSONList() {

$.ajax({

url: 'getJSONList',

type: 'get',

dataType: 'json',

success: function ( objList ) {

var array = objList;

$('#content3').empty();

$.each(array, function(i, user) {

$('#content3').append('<tr>');

$('#content3').append('<td>' + (i + 1) + '</td>');

$('#content3').append('<td>' + user.name + '</td>');

$('#content3').append('<td>' + user.age + '</td>');

$('#content3').append('</tr>');

});

},

error: function() {

alert('실패');

}

});

}

 

function fn_sendJSON() {

 

var name = $('#name').val();

var age = $('#age').val();

var sendObj = { // 객체이자 json 데이터

"name": name,

"age": age

};

$.ajax({

url: 'sendJSON',

type: 'post', // @PostMapping

data: JSON.stringify(sendObj), // json데이터를 그냥 보내게 되면(sendObj) 중간에 유실됨. 그래서 stringify를 이용해 문자열로 변환해서 보내줄것이다.

contentType: 'application/json', // 받을때:dataType. 보낼때: contentType

dataType: 'json',

success: function (obj) {

$('#content4').empty();

$('#content4').append('Name: ' + obj.name + '<br/>');

$('#content4').append('Age: ' + obj.age + '<br/>');

},

error: function() {

alert('실패');

}

});

}

});

 

4. controller

 

 

결과창