Web/Spring

[Spring] Restful API

hikr90 2025. 1. 9. 22:07

# REST

- Representational State Transfer의 약자로, 하나의 uri가 고유한 리소스를 처리하는 공통 방식

- (예, /board/1 로 요청할 시 고정적으로 게시판의 첫번째 글이 해당되도록 지정)

- Rest방식으로 제공되는 API를 Rest API (또는 Restful API) 라고 한다.

 

 

[참고] URI와 URL, URN의 차이

구분 의미
URI
(Uniform Resource Identifier)
- 통합자원 식별자
- 인터넷의 자원(논리적, 물리적 리소스)을 특정하는 고유 주소 값을 뜻한다.

- URI는 URL(위치) 과 URN (자원 명칭)을 포함한다.
- https://test.com/test/uri.jsp?testId=1234
URL
(Uniform Resource Locator)
- 인터넷 상 자원의 위치를 뜻한다.
- 일반적으로 웹 사이트의 위치를 뜻하나 컴퓨터 네트워크 자원의 위치까지 나타낼 수 있다. 
- https://test.com/test/
URN
(Uniform Resource Name)
- 인터넷 자원의 명칭을 뜻한다.
- 명칭을 이용하여 인터넷 상의 특정 자원을 식별할 수 있다.

 

 

Rest 관련 용어

타입 의미
# 어노테이션
@PathVariable - 브라우저에서 요청하는 URL로 전달된 매개변수를 가져오는 어노테이션
- { } 내의 값이 @ PathVariable로 지정되어 요청 URL에서 지정된 값이 { } 에 자동으로 할당된다.
- NULL이나 공백이 들어가는 값은 인식하지 못한다.
- 메소드의 데이터 타입과 다른 타입의 값이 들어가는 경우 오류가 발생한다.
@RequestBody - 브라우저에서 전달되는 JSON 데이터를 객체로 자동 변환해주는 어노테이션
- Html화면의 바디 영역 전체를 받아오는 방식으로, 바디가 없는 get 방식으로는 받아올 수 없다.
@ResponseBody - 데이터 타입 리턴 메소드임을 명시하는 어노테이션
- 해당 어노테이션이 있는 메소드는 Jsp가 아닌 텍스트나 JSON타입으로 결과를 반환한다.
# 메소드
ResponseEntity
- @RestController 사용 시, 데이터 전달 과정에서 발생하는 예외를 제어하는 클래스
- 데이터 전송 중 예외가 발생한 경우 해당 클래스에서 예외 처리 작업이 가능하다.

 

 

# Restful API

- Http URI에 명시한 자원을 통해서 Http Method (추가, 수정, 삭제) 의 작업을 통해서 CRUD 작업을 진행하는 것

- /작업명/기본키 + 메소드 + 데이터 의 형태로 진행한다.

 

 

메소드

메소드 의미
POST 추가 (CREATE)
GET 조회 (SELECT)
PUT 수정 (UPDATE)
DELETE 삭제 (DELETE)

 

 

[예시]  Rest API

# TestController.java (Rest메소드 컨트롤러)

package com.korea.ctr;


import java.util.HashMap;
import java.util.List;

import org.apache.ibatis.io.ResolverUtil.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.korea.daoImpl.TestDaoImpl;
import com.korea.service.TestService;
import com.korea.serviceImpl.TestServiceImpl;
import com.korea.vo.TestVO;

@RestController
@RequestMapping("/test/*")
public class TestController {
	//
	public static final String VIEW_PATH = "/WEB-INF/views/test/";

	//
	@Autowired
	TestService test_service;
	
	// 목록 전체 조회
	@RequestMapping("/test_list")
	public List<TestVO> test_list(Model model) throws Exception {
		List<TestVO> list = null;
		list = test_service.test_list(model);
		return list;
	}
	
	// 데이터 단건 조회
	@RequestMapping(value = {"/{test_no}"}, method = RequestMethod.GET)
	public TestVO test_vo(Model model, @PathVariable("test_no") String test_no) throws Exception {
		//
		TestVO vo = null;
		vo = test_service.test_vo(model, test_no);
		//
		return vo;
	}
	
	// 새글 등록 
	@RequestMapping(value = {""}, method = RequestMethod.POST)
	public void test_insert(Model model, @RequestBody TestVO vo) throws Exception {
		//
		test_service.test_insert(model, vo);
	}

	// 글 수정
	@RequestMapping(value = {""}, method = RequestMethod.PUT)
	public void test_update(Model model, @RequestBody TestVO vo) throws Exception {
		//
		test_service.test_update(model, vo);
	}

	// 글 삭제
	@RequestMapping(value = {""}, method = RequestMethod.DELETE)
	public void test_delete(Model model, @RequestBody TestVO vo) throws Exception {
		//
		test_service.test_delete(model, vo);
	}
	
}

 

# HomeController.java (확인 컨트롤러)

package com.korea.ctr;


import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.korea.daoImpl.TestDaoImpl;
import com.korea.service.TestService;
import com.korea.serviceImpl.TestServiceImpl;
import com.korea.vo.TestVO;

@Controller
public class HomeController {
	//
	public static final String VIEW_PATH = "/WEB-INF/views/test/";
	//
	@Autowired
	TestService test_service;
	
	// 테스트 목록
	@RequestMapping(value= {"/"})
	public String list(Model model) throws Exception {
		//
		return VIEW_PATH + "test_list.jsp";
	}
	
}

 

# TestServiceImpl.java

package com.korea.serviceImpl;

import java.util.HashMap;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;

import com.korea.dao.TestDao;
import com.korea.service.TestService;
import com.korea.vo.TestVO;

@Service
@Transactional
public class TestServiceImpl implements TestService{
	
	@Autowired
	TestDao test_dao;
	
	//
	public List<TestVO> test_list(Model model) throws Exception {
		List<TestVO> list = test_dao.test_list();
		return list;
	}
	
	//
	public TestVO test_vo(Model model, String test_no) throws Exception{
		//
		TestVO vo = new TestVO();
		vo = test_dao.test_vo(test_no);
		//
		return vo;
	}

	//
	public void test_insert(Model model, TestVO vo) throws Exception{
		//
		test_dao.test_insert(vo);
	}

	//
	public void test_update(Model model, TestVO vo) throws Exception{
		//
		test_dao.test_update(vo);
	}

	//
	public void test_delete(Model model, TestVO vo) throws Exception{
		//
		test_dao.test_delete(vo);
	}

}

 

# TestDaoImpl.java

package com.korea.daoImpl;

import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.korea.dao.TestDao;
import com.korea.vo.TestVO;

@Repository
public class TestDaoImpl implements TestDao{
	
	@Autowired
	SqlSession sqlSession;
	
	// 
	public List<TestVO> test_list(){
		List<TestVO> list = sqlSession.selectList("test.test_list");
		return list;
	}
	
	// 
	public TestVO test_vo(String test_no){
		//
		TestVO vo = sqlSession.selectOne("test.test_vo", test_no);
		return vo;
	}
	
	//
	public void test_insert(TestVO vo) {
		//
		sqlSession.insert("test.test_insert", vo);
	}
	
	//
	public void test_update(TestVO vo) {
		//
		sqlSession.update("test.test_update", vo);
	}

	//
	public void test_delete(TestVO vo) {
		//
		sqlSession.delete("test.test_delete", vo);
	}

}

 

# test.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="test">
	
	<select id="test_list" resultType="test">
		SELECT * FROM TEST
	</select>
	
	<select id="test_vo" resultType="test" parameterType="java.lang.String">
		SELECT * FROM TEST WHERE TEST_NO = #{test_no, jdbcType=VARCHAR}
	</select>
	
	<insert id="test_insert" parameterType="test">
		INSERT INTO TEST
		(
			TEST_NO,
			TEST_NM,
			DISP_ORDER,
			REMARK
		) 
		VALUES
		(
			#{test_no, jdbcType=VARCHAR},
			#{test_nm, jdbcType=VARCHAR},
			NULL,
			NULL
		)
	</insert>
	
	<update id="test_update" parameterType="test">
		UPDATE TEST
			SET TEST_NM = #{test_nm, jdbcType=VARCHAR}
			WHERE TEST_NO = #{test_no, jdbcType=VARCHAR}
	</update>
	
	<delete id="test_delete" parameterType="test">
		DELETE FROM TEST
			WHERE TEST_NO = #{test_no, jdbcType=VARCHAR} 
	</delete>
</mapper>

 

# test_list.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 charset="UTF-8">
<title>Insert title here</title>
<script src="${ pageContext.request.contextPath }/resources/httpRequest.js"></script>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript">
	//
	$(function() {
		//
		$("#btn").click(function() {
			//
			if($("#test_no").val()==""){
				alert("테스트 번호를 입력하세요.");
				return;
			}
			if($("#test_nm").val()==""){
				alert("테스트 명칭을 입력하세요.");
				return;
			}
			
			//
			var type = $("input[name='api']:checked").attr("id");
			var url = "${pageContext.request.contextPath}/test/";
			var data_no = $("#test_no").val();
			var data_nm = $("#test_nm").val();
			
			var data = {
					test_no:data_no,
					test_nm:data_nm
			};
			
			//
			$.ajax({
				type:type,
				url:url,
				contentType:"application/json",
				data:JSON.stringify(data),
				success:function(data, textStatus){
					//
					alert("작업이 성공적으로 완료되었습니다.");
				},
				error:function(data, textStatus){
					//
					alert("작업에 실패했습니다.");
				}
			});
			
		});
	});
</script>
</head>
<body>
<form id="form">
	<h1>테스트 목록</h1>
	<input type="button" id="btn" name="btn" value="API동작" />
	<table border="1">
		<caption>:: 테스트 화면 ::</caption>
		<tr>
			<th>테스트 번호</th>
			<td>
				<input type="text" id="test_no" name="test_no" value="" />
			</td>
		</tr>
		<tr>
			<th>테스트 명칭</th>
			<td>
				<input type="text" id="test_nm" name="test_nm" value="" />
			</td>
		</tr>
		<tr>
			<td colspan="2">
				<input type="radio" name="api" id="post" checked="checked" />POST
				<input type="radio" name="api" id="put" />PUT
				<input type="radio" name="api" id="delete" />DELETE
			</td>
		</tr>
	</table>
</form>
</body>
</html>

 

 

[참고] Restful API 요청 및 결과

(1) 전체 및 단건 조회

(2) 등록 (Post)

 

(3) 수정 (Put)

 

(4) 삭제 (Delete)

 

'Web > Spring' 카테고리의 다른 글

[Spring] XML 설정 파일  (0) 2025.01.09
[Spring] Mybatis  (0) 2025.01.09
[Spring] 관점지향 프로그래밍  (0) 2025.01.09
[Spring] 어노테이션  (0) 2025.01.09
[Spring] MVC 디자인 패턴  (0) 2025.01.09