개념 정리
이전까지는 @RequestParam으로 사용자 입력 값을 가져오고, Model을 사용하여 addAtribute로 데이터를 보내서 출력했다.
하지만 REST API를 사용한다면 JSON 형식의 데이터를 주고 받는다.
@RequestBody로 사용자 입력 값을 가져오고 @ResponseBody로 데이터를 보내준다.
그리고 View만 출력하는 ViewController와 REST API 메서드만 모여있는 ApiController를 구분해서 구현한다.
ApiController 클래스는 @RestController 어노테이션을 준다. (@RestController = @Controller + @ResponseBody)
RestController의 주요 메소드는 GET, POST(create), DELETE, PUT(update)이다.
ApiController 메서드의 return 값은 DTO 클래스를 생성하여 DTO에 담아서 보낸다. 또한 Map, List도 담아서 보낼 수 있다.
Rest API 구현 순서
- ViewController와 ApiController는 따로 나눠서 생성한다.
- ViewController를 생성한다.
- 클래스에 @Controller 어노테이션을 준다.
- main이나 Form 출력같이 로직과 전달 값 없고, 오로지 View만 출력하는 메소드로만 구성한다.
- 해당 메소드의 return 값은 이동할 html 파일명을 주는 @Getmapping 메소드이다.
- 예시
-
public class ViewController { // 메인 출력 @GetMapping("/") public String main() { return "login"; } // 회원가입 폼 출력 @GetMapping("/join") public String viewJoin() { return "join"; } }
-
- RequestDTO/ResponseDTO를 생성한다.
- ApiController 메소드에서 Request할 값이나, Reponse할 값이 있다면 그 값을 담아서 넘겨줄 DTO를 생성한다.
- DTO는 @Data 어노테이션을 주입한다.
- REST API를 구성할 때 return 값 데이터 형태는 DTO, Map, List 형태 모두 가능하다.
- 하지만 나는 왠만해서 DTO를 만들어서 사용하려고 했다.
- 그런데 넘겨줄 값이 한 개이면 그냥 Map으로 선언하여 넘겨주었다! (고민: 값 1개를 넘겨줘도 DTO를 만들어서 사용하는게 나을지?)
- 예시
-
// ApiController의 join 메소드 사용 @Data public class JoinReqDTO { private String inputName; private String inputEmail; private String inputPw; } ------------------------------------- // ApiController의 login 메소드 사용 @Data public class LoginReqDTO { private String inputName; private String inputPw; }
-
- ApiController를 생성한다.
- 클래스에 @RestController 어노테이션을 준다.
- 아직 전체 메소드를 RESTFUL하게 만들지 못하였다면 먼저 @Controller 어노테이션을 주입하고 REST 메소드에 @ResponseBody를 붙여서 점점 만들어 나간다.
- 예시
-
// 회원가입 @PostMapping("/join") @ResponseBody public List<Member> join(@RequestBody JoinReqDTO joinReqDTO) { Member member = Member.builder() .username(joinReqDTO.getInputName()) .email(joinReqDTO.getInputEmail()) .password(joinReqDTO.getInputPw()) .joindate(LocalDate.now()) .build(); memberList.add(member); return memberList; }
-
- 예시
- 아직 전체 메소드를 RESTFUL하게 만들지 못하였다면 먼저 @Controller 어노테이션을 주입하고 REST 메소드에 @ResponseBody를 붙여서 점점 만들어 나간다.
- REST API 메소드를 생성한다.
- 매개변수에서 받아올 값은 @RequestBody와 위에서 만든 RequestDTO를 사용하여 JSON 형태로 값을 받아온다.
- 예시
- join(@RequestBody JoinReqDTO joinReqDTO)
- 예시
- 엔티티에 저장할 값(POST)이 있다면 builder()를 사용하여 값을 넣어준다.
- 해당 엔티티 클래스에는 @Builder 어노테이션이 붙여진 상태여야 한다.
- 예시
-
Member member = Member.builder() .username(joinReqDTO.getInputName()) .email(joinReqDTO.getInputEmail()) .password(joinReqDTO.getInputPw()) .joindate(LocalDate.now()) .build();
-
- 보낼 값(Reponse)의 데이터 타입은 위에서 생성한 DTO나 Map, List 형태 모두 가능하다.
- 메소드에 @ResponseBody 어노테이션을 붙여주거나, @RestController가 붙은 컨트롤러 클래스라면 자동으로 3가지의 데이터를 모두 JSON으로 자동변환하여 넘겨주기 때문이다.
- 예시
-
// Map 형태 @PostMapping("/") public Map<String, String> login(@RequestBody LoginReqDTO loginReqDTO) { String message = "로그인 실패!"; String inputName = loginReqDTO.getInputName(); String inputPw = loginReqDTO.getInputPw(); for(Member member: memberList) { if(member.getUsername().equals(inputName) && member.getPassword().equals(inputPw)) { message = "로그인 성공!"; break; } } Map<String, String> loginResMap = new HashMap<>(); loginResMap.put("message", message); return loginResMap; } // List 형태 // 회원가입 @PostMapping("/join") public List<Member> join(@RequestBody JoinReqDTO joinReqDTO) { Member member = Member.builder() .username(joinReqDTO.getInputName()) .email(joinReqDTO.getInputEmail()) .password(joinReqDTO.getInputPw()) .joindate(LocalDate.now()) .build(); memberList.add(member); return memberList; }
-
- 매개변수에서 받아올 값은 @RequestBody와 위에서 만든 RequestDTO를 사용하여 JSON 형태로 값을 받아온다.
- 클래스에 @RestController 어노테이션을 준다.
- html에서 fetch()를 사용하여 스크립트 함수를 작성한다.
- Request만 있고 Response 값이 없을 때 예시
-
const join = () => { const inputName = document.getElementById("inputName").value; const inputEmail = document.getElementById("inputEmail").value; const inputPw = document.getElementById("inputPw").value; fetch("/join", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ inputName: inputName, inputPw: inputPw, inputEmail: inputEmail }) }) .then(response => { if (response.ok) { window.location.href = "/"; } else { console.error("회원가입 실패"); } }) .catch(error => { console.error("오류 발생: ", error); }) }
- 값을 보낼 때 input 태그에 있던 id의 값을 document.getElementById(”id값").value; 을 변수에 담는다.
- 이후 위의 변수를 body에서 JSON 형태로 보낸다. {변수명: 변수명, ….}
- 실행 후 경로 이동이 있다면 window.location.href = "경로"; 의 형태로 작성한다.
-
- Request와 Response 값이 모두 있을 때 예시
-
const login = () => { const inputName = document.getElementById("inputName").value; const inputPw = document.getElementById("inputPw").value; fetch("/", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ inputName: inputName, inputPw: inputPw }) }) .then(response => response.json()) .then(data => { document.getElementById("alert").innerText = data.message; }) .catch(error => { console.error('Error:', error); }); }
- Request는 위의 방법과 같고, Reponse 값은 .then() 안에서 data(json)를 가져온 후, data.키이름 형식으로 값을 가져온다.
- 예시
- .then(data => {document.getElementById("alert").innerText = data.message;})
- 예시
- div 태그의 값을 Reponse한 값으로 변경하려면 document.getElementById("id명").innerText 로 변경한다.
-
- Request만 있고 Response 값이 없을 때 예시
728x90
'Back-end > Spring Boot' 카테고리의 다른 글
[Spring Boot] URI 어노테이션 (0) | 2024.04.06 |
---|---|
[Spring DB] DB 관련 어노테이션, 데이터 모델링 클래스 (0) | 2024.04.06 |
[Spring Boot] Test (0) | 2024.04.06 |
[Spring DB] Repository (JPA, JPQL, Native SQL) (0) | 2024.04.06 |
[Spring Boot] Devtools, LocaleResolver(다국어 처리) (0) | 2024.04.03 |