[포스코x코딩온] 웹개발자 풀스택 부트캠프8기

[포스코x코딩온] API 만들기(Get, Post, Axios 사용법)

항상 발전하는 개발자 2023. 11. 1. 11:24
728x90

API(Get, Post)

GET 방식

  • Get method의 URL을 받을 때는 Controller에서 @GetMapping(url)을 이용해야 한다.
@GetMapping(url주소)
public String 함수이름() {
	return 템플릿 파일 명;
}

(get) ?key=value

  • ?key=value 형태로 url이 넘어올 때 Controller에서 받는 방법은 @RequestParam 이용하기
@GetMapping(url주소)
public String 함수이름(@RequestParam(value="key") String key){
	return 템플릿 파일명;
}
  • 이때, key라는 변수에 ?key=value로 넘어온 value 값이 들어간다.
  • @RequestParam에 required값을 설정하면 없어도 실행된다.

(get) ~/{value}

  • ~/{value} 형태로 url이 넘어올 때 Controller에서 받는 방법은 @PathVariable 이용하기
@GetMapping(url주소/{value})
public String 함수이름(@PathVariable String value){
	return 템플릿 파일명;
}
  • 이때, value 라는 변수에 url로 넘어온 값이 담긴다.
  • 만약, 이름을 다르게 설정하고 싶으면
@GetMapping(url주소/{value}/{value2})
public String 함수이름(@PathVariable String value, @PathVariable("value2") String abc){
	return 템플릿 파일명;
}
  • value2 위치에 넘어온 값이 abc라는 변수에 담기게 된다.

  • Controller.java
    @GetMapping("/introduce/{name}")
    public String introduce(@PathVariable String name, Model model){
        model.addAttribute("name", name);
        return "practice";
    }
    @GetMapping("/introduce2")
    public String introduce2(@RequestParam String name, @RequestParam String age, Model model){
        model.addAttribute("name", name);
        model.addAttribute("age",age);
        return  "practice";
    }
  • practice.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>practice</title>
</head>
<body>
<p th:text="'내 이름은 ' + ${name}">.</p>
<p th:text="'내 나이는 ' + ${age}">.</p>
</body>
</html>


POST 방식

  • Post method의 URL을 받을 때는 Controller에서 @PostMapping(url)을 이용해야 한다.
@PostMapping(url주소)
public String 함수이름(){
	return 템플릿 파일명;
}

  • Controller.java
package codingon.kdt.kdt8.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class PracticeController {
    @GetMapping("/practice")
    public String main(){
        return "practice_form_request_231031";
    }
    @PostMapping("/post/signup")
    public  String signup(@RequestParam String name, @RequestParam String gender,
    @RequestParam String year,@RequestParam String month,@RequestParam String day,
    @RequestParam String hobby, Model model){
        model.addAttribute("name",name);
        model.addAttribute("gender", gender);
        model.addAttribute("year", year);
        model.addAttribute("month",month);
        model.addAttribute("day", day);
        model.addAttribute("hobby", hobby);
        return "practice_form_post_231031";
    }
}
  • practice_form_request_231031.html
    • 사용자 값을 입력 받는 곳. (/practice일 때 열리는 곳)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div>
    <form action="/post/signup" method="post">
    <p>이름<input type="text" name="name"></p>
    <br>
    <p>성별<input type="radio" value="남자" name="gender">남자 <input type="radio" value="여자" name="gender">여자</p>
    <br>
    <p>생년월일
        <select name="year">
            <option>1990</option>
            <option>1992</option>
            <option>1993</option>
            <option>1994</option>
            <option>1995</option>
            <option>1996</option>
            <option>1997</option>
            <option>1998</option>
            <option>1999</option>
            <option>2000</option>
    </select>년
    <select name="month">
        <option>1</option>
        <option>2</option>
        <option>3</option>
        <option>4</option>
        <option>5</option>
        <option>6</option>
        <option>7</option>
        <option>8</option>
        <option>9</option>
        <option>10</option>
        <option>11</option>
        <option>12</option>
    </select>월
    <select name="day">
        <option>1</option>
        <option>2</option>
        <option>3</option>
        <option>4</option>
        <option>5</option>
        <option>6</option>
        <option>7</option>
        <option>8</option>
        <option>9</option>
        <option>10</option>
        <option>11</option>
        <option>12</option>
        <option>13</option>
        <option>14</option>
        <option>15</option>
        <option>16</option>
        <option>17</option>
        <option>18</option>
        <option>19</option>
        <option>20</option>
        <option>21</option>
        <option>22</option>
        <option>23</option>
        <option>24</option>
        <option>25</option>
        <option>26</option>
        <option>27</option>
        <option>28</option>
        <option>29</option>
        <option>30</option>
    </select>일</p>
    <br>
    <p>관심사<input type="checkbox" value="여행" name="hobby">여행
        <input type="checkbox" value="패션" name="hobby">패션
        <input type="checkbox" value="음식" name="hobby">음식</p>
    <br>
    <button type="submit">회원가입</button>
    </form>
</div>
</body>
</html>
  • practice_form_post_231031.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<p th:text="'이름: ' + ${name}"></p>
<p th:text="'성별: ' + ${gender}"></p>
<p th:text="'생년월일: ' + ${year} + '-'+ ${month}+ '-' + ${day}"></p>
<p th:text="'관심사: ' + ${hobby}"></p>
</body>
</html>


API로 이용하기

  • 앞에서 배운 방식으로 return을 이용해 Template view를 무조건 불러왔다.
  • 하지만, API로만 데이터를 전달할 수도 있다.
  • @ResponseBody를 이용하면 된다.
@GetMapping("response-string")
@ResponseBody
public String getString(@RequestParam("name") String name){return "hello" + name;}
  • Node.js에서의 res.send()와 동일하다고 생각해도 된다.

DTO 이용하기

  • request.html
<h2>DTO 이용하기</h2>
<div style="display: flex">
    <form action="/dto/response1" method="get" style="margin-right: 20px;">
        <h3>Get - DTO</h3>
        이름 : <input type="text" name="name">
        <br>
        나이 : <input type="text" name="age">
        <br>
        <button type="submit">GET 전송</button>
    </form>
    <form action="/dto/response2" method="post" style="margin-right: 20px;">
        <h3>Post - DTO</h3>
        이름 : <input type="text" name="name">
        <br>
        나이 : <input type="text" name="age">
        <br>
        <button type="submit">Post 전송 ( RequestBody x )</button>
    </form>
    <form action="/dto/response3" method="post" style="margin-right: 20px;">
        <h3>Post - DTO</h3>
        이름 : <input type="text" name="name">
        <br>
        나이 : <input type="text" name="age">
        <br>
        <button type="submit">Post 전송 ( RequestBody O )</button>
    </form>
</div>
  • UserDTO.java
    • get, set 함수를 만들어줘야 한다.
package codingon.kdt.kdt8.dto;


public class UserDTO {
    private String name;
    private String age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

}
  • MainController.java
    • @RequestBody를 사용했을 때만 오류가 발생한다.
    • @RequestBody는 json 이나 xml 데이터 형식을 읽기 때문이다.
    • 즉, 일반 폼 Get 방식 DTO(@ModelAttribute)로 전송을 해야한다.
    @GetMapping("/dto/response1")
    @ResponseBody
    public String dtoAPI1(@ModelAttribute UserDTO userDTO){
        //ModelAttribute: html 폼 데이터를 컨트롤러로 전달할 때 사용. get이나 post 전송에서 사용
        String msg = userDTO.getName() +" "+ userDTO.getAge()+"!!!!";
        return msg;
    }
    //일반 폼 Get 방식 - DTO(@ModelAttribute) 전송 가능
    //일반 폼 Get 방식 - DTO(@RequestBody) 오류 발생

    @PostMapping("/dto/response2")
    @ResponseBody
    public String dtoAPI2(UserDTO userDTO){
        String msg = userDTO.getName() + " " + userDTO.getAge() + "!!!";
        return msg;
    }
    @PostMapping("/dto/response3")
    @ResponseBody
    public String dtoAPI3( @RequestBody UserDTO userDTO){
        //RequestBody : json 또는 xml 데이터 형식을 읽는다.(axios)
        //일반 폼 전송 시 데이터 형식은 기본값으로 x-www-form-urlencoded
        String msg = userDTO.getName() + " " + userDTO.getAge() + "!!!";
        return msg;
    }

Axios-DTO 이용하기

  • request.html
<script>
    function dtoResponse1() {
        var form = document.getElementById('form_dto1');
        axios.get(`/axios/response1?name=${form.name.value}&age=${form.age.value}`)
        .then((res)=>{
            console.log( res );
            console.log( 'dtoResponse1 : ', res.data );
        });
    }
    function dtoResponse2() {
        var form = document.getElementById('form_dto1');
        axios.get(`/axios/response2?name=${form.name.value}&age=${form.age.value}`)
        .then((res)=>{
            console.log( res );
            console.log( 'dtoResponse2 : ', res.data );
        });
    }
    function dtoResponse3() {
        var form = document.getElementById('form_dto2');
        axios.post(`/axios/response3`, {name: form.name.value, age: form.age.value})
        .then((res)=>{
            console.log( res );
            console.log( 'dtoResponse3 : ', res.data );
        });
    }
    function dtoResponse4() {
        var form = document.getElementById('form_dto2');
        axios.post(`/axios/response4`, {name: form.name.value, age: form.age.value})
        .then((res)=>{
            console.log( res );
            console.log( 'dtoResponse1 : ', res.data );
        });
    }
    function dtoResponse5() {
        var form = document.getElementById('form_dto2');
        axios.post(`/axios/response5`, {name: form.name.value, age: form.age.value})
        .then((res)=>{
            console.log( res );
            console.log( 'dtoResponse5 : ', res.data );
        });
    }
</script>

<br>
<hr>
<h2>DTO 이용하기 - axios</h2>
<div style="display: flex">
    <form action="/axios/response1" method="get" style="margin-right: 20px;" id="form_dto1">
        이름 : <input type="text" name="name">
        <br>
        나이 : <input type="text" name="age">
        <br>
        <button type="button" onclick="dtoResponse1();">GET ( 일반 ) - axios</button>
        <button type="button" onclick="dtoResponse2();">Get ( DTO ) - axios</button>
    </form>
    <form action="/axios/response3" method="post" style="margin-right: 20px;" id="form_dto2">
        <h3>Post ( 일반 ) - axios</h3>
        이름 : <input type="text" name="name">
        <br>
        나이 : <input type="text" name="age">
        <br>
        <button type="button" onclick="dtoResponse3();">Post ( 일반 ) - axios</button>
        <button type="button" onclick="dtoResponse4();">Post ( DTO ) - axios ( RequestBody X )</button>
        <button type="button" onclick="dtoResponse5();">Post ( DTO ) - axios ( RequestBody O )</button>
    </form>
</div>
  • MainController.java
    • axios로 값을 전달하게 되면 파라미터로 값이 들어오지 않는다. 이 상태에서 @RequestParam으로 값을 전달 받으면 required의 기본값이 true이기 때문에 오류가 발생한다.
    @GetMapping("/axios/response1")
    @ResponseBody
    public String axiosResponse1(@RequestParam String name, @RequestParam String age){
        String msg = "이름: " + name + ", 나이: " + age;
        return msg;
    }

    @GetMapping("/axios/response2")
    @ResponseBody
    public String axiosResponse2(UserDTO userDTO){
        String msg = "이름: " + userDTO.getName() + ", 나이: "+ userDTO.getAge();
        return msg;
    }

    @PostMapping("/axios/response3")
    @ResponseBody
    //@RequstParam required 기본값이 true
    //axios로 값을 전달하게 될 경우 파라미터로 값이 들어오지 않는다.(Post로 보냈을 때)
    //값이 들어오지 않는데, @RequestParasm의 required가 기본값이 true이기 때문에 오류
    public String axiosResponse3(@RequestParam String name, @RequestParam String age){
        String msg = "이름: " + name + ", 나이: "+ age;
        return  msg;

    }

    @PostMapping("/axios/response4")
    @ResponseBody
    public String axiosResponse4(UserDTO userDTO){
        String msg = "이름:" + userDTO.getName() + ", 나이: "+ userDTO.getAge();
        return msg;
    }

    @PostMapping("/axios/response5")
    @ResponseBody
    public String axiosResponse5(@RequestBody UserDTO userDTO){
        String msg = "이름:" + userDTO.getName() + ", 나이: "+ userDTO.getAge();
        return msg;
    }
    //@RequestParam @ModelAttribute : 매개변수(파라미터)로 전달된 친구들을 변환
    //@RequestBody: json 형태의 데이터 (데이터)

VO 이용하기

  • request.html
<h2>VO 이용하기</h2>
<div style="display: flex">
    <form action="/vo/response1" method="get" style="margin-right: 20px;">
        <h3>Get - VO</h3>
        이름 : <input type="text" name="name">
        <br>
        나이 : <input type="text" name="age">
        <br>
        <button type="submit">GET 전송</button>
    </form>
    <form action="/vo/response2" method="post" style="margin-right: 20px;">
        <h3>Post - VO</h3>
        이름 : <input type="text" name="name">
        <br>
        나이 : <input type="text" name="age">
        <br>
        <button type="submit">Post 전송 ( RequestBody x )</button>
    </form>
    <form action="/vo/response3" method="post" style="margin-right: 20px;">
        <h3>Post - VO</h3>
        이름 : <input type="text" name="name">
        <br>
        나이 : <input type="text" name="age">
        <br>
        <button type="submit">Post 전송 ( RequestBody O )</button>
    </form>
</div>
  • UserVO.java
    • VO의 경우에는 set 함수를 만들지 않는다.
package codingon.kdt.kdt8.vo;

public class UserVO {
    private String name;
    private String age;

    public String getName() {
        return name;
    }

    public String getAge() {
        return age;
    }
}
  • MainController.java
    • set함수를 만들지 않음으로 null값이 발생한다.
    @GetMapping("/vo/response1")
    @ResponseBody
    public String voAPI1(UserVO userVO){
        String msg = userVO.getName() + " " + userVO.getAge() + "!!!";
        return msg;
    }

Axios-VO 이용하기

  • request.html
<script>
    function voResponse1() {
        var form = document.getElementById('form_vo1');
        axios.get(`/axios/vo/response1?name=${form.name.value}&age=${form.age.value}`)
        .then((res)=>{
            console.log( res );
            console.log( 'dtoResponse1 : ', res.data );
        });
    }
    function voResponse2() {
        var form = document.getElementById('form_vo1');
        axios.get(`/axios/vo/response2?name=${form.name.value}&age=${form.age.value}`)
        .then((res)=>{
            console.log( res );
            console.log( 'voResponse2 : ', res.data );
        });
    }
    function voResponse3() {
        var form = document.getElementById('form_vo2');
        axios.post(`/axios/vo/response3`, {name: form.name.value, age: form.age.value})
        .then((res)=>{
            console.log( res );
            console.log( 'voResponse3 : ', res.data );
        });
    }
    function voResponse4() {
        var form = document.getElementById('form_vo2');
        axios.post(`/axios/vo/response4`, {name: form.name.value, age: form.age.value})
        .then((res)=>{
            console.log( res );
            console.log( 'voResponse4 : ', res.data );
        });
    }
    function voResponse5() {
        var form = document.getElementById('form_vo2');
        axios.post(`/axios/vo/response5`, {name: form.name.value, age: form.age.value})
        .then((res)=>{
            console.log( res );
            console.log( 'voResponse5 : ', res.data  );
        });
    }
</script>

<br>
<hr>
<h2>VO 이용하기 - axios</h2>
<div style="display: flex">
    <form id="form_vo1" style="margin-right: 20px;">
        <h3>Get ( 일반 ) - axios</h3>
        이름 : <input type="text" name="name">
        <br>
        나이 : <input type="text" name="age">
        <br>
        <button type="button" onclick="voResponse1();">GET ( 일반 ) - axios</button>
        <button type="button" onclick="voResponse2();">Get ( VO ) - axios</button>
    </form>
    <form id="form_vo2" style="margin-right: 20px;">
        <h3>Post ( 일반 ) - axios</h3>
        이름 : <input type="text" name="name">
        <br>
        나이 : <input type="text" name="age">
        <br>
        <button type="button" onclick="voResponse3();">Post ( 일반 ) - axios</button>
        <button type="button" onclick="voResponse4();">Post ( VO ) - axios ( RequestBody X )</button>
        <button type="button" onclick="voResponse5();">Post ( VO ) - axios ( RequestBody O )</button>
    </form>
</div>
  • MainController.java
    • @RequestBody로 값을 전달하면 userVO에 setter 함수가 없어도 값이 들어간다.(필드에 내장된 set 함수를 실행한다.)
@PostMapping("/axios/vo/response4")
    @ResponseBody
    public String axiosVoResponse4(UserVO userVO){
        String msg = "이름: "+ userVO.getName() + ", 나이: "+ userVO.getAge();
        return msg;
    }

    @PostMapping("/axios/vo/response5")
    @ResponseBody
    public String axiosVoResponse5(@RequestBody UserVO userVO){
        //@RequestBody로 값을 전달할때 userVO에 setter 함수가 없어도 값이 들어간다.
        //@RequestBody는 setter 함수 실행이 아니라 각각의 필드(변수)에 직접적으로 값을 주입하면서 매핑
        //@ModelAttribute가 setter 함수를 실행해 값을 넣어준다면
        //@RequestBody는 각각의 필드(변수)에 직접적으로 값을 주입한다. 필드에 내장된 set 함수를 실행
        String msg = "이름: "+ userVO.getName() + ", 나이: "+ userVO.getAge();
        return msg;
    }

총 정리

  1. 일반 폼 전송 시
    • RequestParam : Get과 Body 둘 다 가능
    • ParamVariable : Get만 가능
  2. DTO 이용 - 일반 폼 전송
    • Get 전송 가능
    • Post 전송 - RequestBody가 없을 경우 가능
    • Post 전송 - RequestBody가 있을 경우 실패
  3. VO 이용 - 일반 폼 전송
    • Get 전송 Null
    • Post 전송 - RequestBody가 없을 경우 Null
    • Post 전송 - RequestBody가 있을 경우 실패
  4. Axios 이용 - DTO
    • Get 일반 : 가능
    • Get DTO : 가능
    • Post 일반 : 실패
    • Post DTO - RequestBody가 없을 경우 : Null
    • Post DTO - RequestBody가 있을 경우 : 가능
  5. Axios 이용 - VO
    • Get 일반 : 가능
    • Get DTO : 가능
    • Post 일반 : 실패
    • Post DTO - RequestBody가 없을 경우 : Null
    • Post DTO - RequestBody가 있을 경우 : 가능

@RequestBody

  • View에서 Controller로 값을 전달할 때 HTTP Body 안에 JSON을 VO에 매핑시켜주는 Spring Annotation
  • IntroduceVO에는 Setter이 없음에도 값이 할당된다.
728x90