Restful, Rest API
Rest
- "Representational StateTransfer"
- HTTP URI(Uniform Resource Identifier)를 통해 자원(Resource)을 명시하고, HTTP Method(POST, GET, PUT, DELETE)를 통해 해당 자원에 대한 CRUD Operation을 적용하는 것이다.
- 자원을 이름으로 구분하여 해당 자원의 상태(정보)를 주고 받는 모든 것을 의미한다.
- 월드 와이드 웹과 같은 분산 하이퍼미디어 시스템을 위한 소프트웨어 개발 아키텍처의 한 형식이다.
- 기본적으로 웹의 기존 기술과 HTTP 프로토콜을 그대로 활용한다.
- REST는 네트워크 상에서 Client와 Server 사이의 통신 방식 중 하나이다.
Rest API
- RestController로 구현한다.
- REST는 HTTP 표준을 기반으로 구현하므로, HTTP를 지원하는 프로그램 언어로 클라이언트, 서버를 구현할 수 있다.
출처 : https://gmlwjd9405.github.io/2018/09/21/rest-and-restful.html
Restful : 주소를 통해 결과를 취득한다.
ajax로 접근하는데 전송 방식에 따라 메소드를 구분해서 쓴다.
전송 방식 5가지
1) POST : 데이터 전달
2) GET : 데이터 전달
3) PUT : 등록
4) PATCH : 수정
5) DELETE : 삭제
단순 조회만 쓰는 게 아니라 등록, 수정, 삭제 다 쓸 수 있음.
리퀘스트 맵핑 쓰던 거랑 별 차이 없음. 메소드만 바뀐 것.
RestfulController.java
@RestController : Controller 역할을 하나, 해당 컨트롤러 안의 메소드들은 모두 ResponseBody 처리를 한다. ResponseBody 안 써도 ViewResolver 동작 안 하고 다이렉트로 실행됨.
@RequestMapping + method -> GetMapping, PostMapping, PutMapping 등등...
똑같은 주소인데 전송방식에 따라 다르게 할당한다.
ajax로 부르면 되는데 굳이 제이슨으로 안 받아도 되는 건 데이터타입 text
예를 들어 put은 문자열만 돌아오기 때문에
이런 식으로 메소드만 다르게 주면 동일 주소라도 다르게 쓸 수 있다.
디벨로퍼 켜고
--------------------------------------------------------
-- Drop
--------------------------------------------------------
DROP TABLE "REST";
--------------------------------------------------------
-- DDL for Table REST
--------------------------------------------------------
CREATE TABLE "REST"
( "RTXT" VARCHAR2(100 BYTE),
"RDT" DATE DEFAULT SYSDATE
) ;
COMMENT ON COLUMN "REST"."RTXT" IS '텍스트';
COMMENT ON COLUMN "REST"."RDT" IS '등록일';
Insert into REST (RTXT,RDT) values ('홍길동',TO_DATE('20220516145001', 'YYYYMMDDHH24MISS'));
Insert into REST (RTXT,RDT) values ('신사임당',TO_DATE('20220516145003', 'YYYYMMDDHH24MISS'));
Insert into REST (RTXT,RDT) values ('김철수',TO_DATE('20220516145005', 'YYYYMMDDHH24MISS'));
Insert into REST (RTXT,RDT) values ('허준',TO_DATE('20220516145007', 'YYYYMMDDHH24MISS'));
Insert into REST (RTXT,RDT) values ('유관순',TO_DATE('20220516145009', 'YYYYMMDDHH24MISS'));
--------------------------------------------------------
-- Constraints for Table REST
--------------------------------------------------------
ALTER TABLE "REST" MODIFY ("RTXT" NOT NULL ENABLE);
ALTER TABLE "REST" MODIFY ("RDT" NOT NULL ENABLE);
COMMIT;
F5 눌러서 테이블 만들고
RestfulController
package com.spring.sample.web.sample.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RestController;
import com.spring.sample.web.sample.service.IRestfulService;
@RestController
public class RestfulController {
@Autowired
public IRestfulService irfs;
@GetMapping(value = "/restApi", produces = "application/json;charset=UTF-8")
public List<String> getList() throws Throwable {
List<String> list = irfs.getList();
return list;
}
@PostMapping(value = "/restApi", produces = "application/json;charset=UTF-8")
public List<String> postList() throws Throwable {
List<String> list = irfs.getList();
return list;
}
@PutMapping(value = "/restApi", produces = "application/json;charset=UTF-8")
public String putOne() throws Throwable {
irfs.putOne();
String txt = irfs.getBottom();
return txt;
}
@PatchMapping(value = "/restApi", produces = "application/json;charset=UTF-8")
public String patchOne() throws Throwable {
irfs.patchOne();
String txt = irfs.getTop();
return txt;
}
@DeleteMapping(value = "/restApi", produces = "application/json;charset=UTF-8")
public List<String> deleteOne() throws Throwable {
irfs.deleteOne();
List<String> list = irfs.getList();
return list;
}
}
IRestfulService
package com.spring.sample.web.sample.service;
import java.util.List;
public interface IRestfulService {
public List<String> getList() throws Throwable;
public void putOne() throws Throwable;
public String getTop() throws Throwable;
public String getBottom() throws Throwable;
public void patchOne() throws Throwable;
public void deleteOne() throws Throwable;
}
RestfulService
package com.spring.sample.web.sample.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.spring.sample.web.sample.dao.IRestfulDao;
@Service
public class RestfulService implements IRestfulService {
@Autowired
public IRestfulDao irfd;
@Override
public List<String> getList() throws Throwable {
return irfd.getList();
}
@Override
public void putOne() throws Throwable {
irfd.putOne();
}
@Override
public String getTop() throws Throwable {
return irfd.getTop();
}
@Override
public String getBottom() throws Throwable {
return irfd.getBottom();
}
@Override
public void patchOne() throws Throwable {
irfd.patchOne();
}
@Override
public void deleteOne() throws Throwable {
irfd.deleteOne();
}
}
IRestfulDao
package com.spring.sample.web.sample.dao;
import java.util.List;
public interface IRestfulDao {
public List<String> getList() throws Throwable;
public void putOne() throws Throwable;
public String getTop() throws Throwable;
public String getBottom() throws Throwable;
public void patchOne() throws Throwable;
public void deleteOne() throws Throwable;
}
RestfulDao
package com.spring.sample.web.sample.dao;
import java.util.List;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@Repository
public class RestfulDao implements IRestfulDao {
@Autowired
public SqlSessionTemplate sql;
@Override
public List<String> getList() throws Throwable {
return sql.selectList("rest.getList");
}
@Override
public void putOne() throws Throwable {
sql.insert("rest.putOne");
}
@Override
public String getTop() throws Throwable {
return sql.selectOne("rest.getTop");
}
@Override
public String getBottom() throws Throwable {
return sql.selectOne("rest.getBottom");
}
@Override
public void patchOne() throws Throwable {
sql.update("rest.patchOne");
}
@Override
public void deleteOne() throws Throwable {
sql.delete("rest.deleteOne");
}
}
Rest_SQL.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="rest">
<select id="getList" resultType="String">
SELECT RTXT
FROM REST
ORDER BY RDT ASC
</select>
<select id="getTop" resultType="String">
SELECT RTXT
FROM (SELECT RTXT, ROW_NUMBER() OVER(ORDER BY RDT ASC) AS RNUM
FROM REST) R
WHERE R.RNUM = 1
</select>
<select id="getBottom" resultType="String">
SELECT RTXT
FROM (SELECT RTXT, ROW_NUMBER() OVER(ORDER BY RDT DESC) AS RNUM
FROM REST) R
WHERE R.RNUM = 1
</select>
<insert id="putOne">
INSERT INTO REST (RTXT)
VALUES ('TEST' || (SELECT COUNT(*) + 1 FROM REST))
</insert>
<update id="patchOne">
UPDATE REST SET RTXT = RTXT || '수정'
WHERE RTXT = (SELECT RTXT
FROM (SELECT RTXT, ROW_NUMBER() OVER(ORDER BY RDT ASC) AS RNUM
FROM REST) R
WHERE R.RNUM = 1)
</update>
<delete id="deleteOne">
DELETE FROM REST
WHERE RTXT = (SELECT RTXT
FROM (SELECT RTXT, ROW_NUMBER() OVER(ORDER BY RDT ASC) AS RNUM
FROM REST) R
WHERE R.RNUM = 1)
</delete>
</mapper>
rest.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Restful Sample</title>
<link rel="shortcut icon" href="resources/favicon/favicon.ico">
<link rel="stylesheet" type="text/css" href="resources/css/common/cmn.css" />
<style type="text/css">
#res {
resize: none;
border: 1px solid #444;
margin: 10px;
}
</style>
<!-- jQuery Script -->
<script type="text/javascript"
src="resources/script/jquery/jquery-1.12.4.min.js"></script>
<script type="text/javascript"
src="resources/script/common/common.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$("#getListBtn").on("click", function() {
$.ajax({
url: "restApi",
method: "GET",
dataType: "json",
success: function (res) {
let txt = "";
txt += "==============\n";
txt += "GET Test Data\n";
txt += "==============\n";
for(const data of res) {
txt += data + "\n";
}
txt += "==============\n";
$('#res').append(txt);
}
});
});
$("#postListBtn").on("click", function() {
$.ajax({
url: "restApi",
method: "POST",
dataType: "json",
success: function (res) {
let txt = "";
txt += "==============\n";
txt += "POST Test Data\n";
txt += "==============\n";
for(const data of res) {
txt += data + "\n";
}
txt += "==============\n";
$('#res').append(txt);
}
});
});
$("#putBtn").on("click", function() {
$.ajax({
url: "restApi",
method: "PUT",
dataType: "text",
success: function (res) {
console.log("aaaaa");
console.log(res);
let txt = "Add : " + res + "\n";
$('#res').append(txt);
}
});
});
$("#patchBtn").on("click", function() {
$.ajax({
url: "restApi",
method: "PATCH",
dataType: "text",
success: function (res) {
let txt = "Update : " + res + "\n";
$('#res').append(txt);
}
});
});
$("#deleteBtn").on("click", function() {
$.ajax({
url: "restApi",
method: "DELETE",
dataType: "json",
success: function (res) {
let txt = "";
txt += "==============\n";
txt += "Delete Result Data\n";
txt += "==============\n";
for(const data of res) {
txt += data + "\n";
}
txt += "==============\n";
$('#res').append(txt);
}
});
});
});
</script>
</head>
<body>
<div class="cmn_title">Rest Api 샘플<div class="cmn_btn_mr float_right_btn" id="sampleListBtn">샘플목록</div></div>
<div>
<div class="cmn_btn_ml" id="getListBtn">GetList</div>
<div class="cmn_btn_ml" id="postListBtn">PostList</div>
<div class="cmn_btn_ml" id="putBtn">PutOne</div>
<div class="cmn_btn_ml" id="patchBtn">PatchTop</div>
<div class="cmn_btn_ml" id="deleteBtn">DeleteTop</div>
</div>
<textarea rows="20" cols="50" id="res" readonly="readonly"></textarea>
</body>
</html>
버튼 누르면 동작함.