[Spring MVC] API 계층 적용하기 (Prac Project - 1. 커피 주문 애플리케이션 시작)
by mignon25커피 주문 애플리케이션의 기능 요구 사항
- 주인이 커피 정보를 관리하는 기능
- 커피 정보 등록 기능
- 등록한 커피 정보 수정 기능
- 등록한 커피 정보 삭제 기능
- 등록한 커피 정보 조회 기능
- 고객이 커피 정보를 조회하는 기능
- 커피 정보 조회 기능
- 고객이 커피를 주문하는 기능
- 커피 주문 등록 기능
- 커피 주문 취소 기능
- 커피 주문 조회 기능
- 고객이 주문한 커피를 주인이 조회하는 기능
- 커피 주문 조회 기능
- 고객에게 전달 완료한 커피에 대한 주문 완료 처리 기능
커피 주문 애플리케이션에 필요한 리소스
REST API 기반의 애플리케이션에서 일반적으로 애플리케이션이 제공해야 할 기능을 리소스(Resource, 자원)로 분류한다.
커피 주문 애플리케이션에는 다음과 같은 리소스가 필요할 것이다.
- 회원(Member)
- 주인과 회원의 구분 : Member의 ROLE을 통해 구분
- 커피(Coffee)
- 주문(Order)
엔트리포인트(Entrypoint) 클래스 작성
Spring Boot 기반의 애플리케이션이 정상적으로 실행되기 위해 가장 먼저 해야할 일은 main() 메서드가 포함된 애플리케이션의 엔트리포인트(Entrypoint, 애플리케이션 시작점)을 작성하는 것이다.
Spring Initializer 를 통해 프로젝트를 생성하게 되면 엔트리포인트 클래스가 자동으로 작성되어 있다.
package com.codestates;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication // 1
public class Section3Week1Application {
public static void main(String[] args) {
SpringApplication.run(Section3Week1Application.class, args); // 2
}
}
- @SpringBootApplication
- 자동 구성 활성화
- 애플리케이션 패키지 내에서 @Component가 붙은 클래스를 검색(scan)한 후, Spring Bean 으로 등록
- @Configuration 이 붙은 클래스를 자동으로 찾아주고, 추가적으로 Spring Bean 등록
- SpringApplication.run(Section3Week1Application.class, args);
- Spring 애플리케이션을 부트스트랩하고, 실행하는 역할
- 부트스트랩 : 애플리케이션이 실행되기 전에 여러가지 설정 작업을 수행하여 실행 가능한 애플리케이션으로 만드는 것.
커피 주문 애플리케이션의 Controller 구조 작성
MemberController 구조 작성
package com.codestates.member;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController // 1
@RequestMapping("v1/members") // 2
public class MemberController {
}
- @RestController
- Spring MVC에서는 특정 클래스에 @RestController를 추가하면 해당 클래스가 REST API의 리소스를 처리하기 위한 API 엔드포인트로 동작한다.
- @RestController 가 추가된 클래스는 애플리케이션 로딩 시, Spring Bean 으로 등록된다.
- @RequestMapping
- 클라이언트의 요청과 클라이언트 요청을 처리하는 핸들러 메서드(Handler Method)를 매핑해주는 역할
- Controller 클래스 레벨에 추가하여 클래스 전체에 사용되는 공통 URL(Base URL) 설정
CoffeeController 구조 작성
package com.codestates.coffee;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/v1/coffees")
public class CoffeeController {
}
OrderController 구조 작성
package com.codestates.order;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/v1/orders")
public class OrderController {
}
핸들러 메서드(Handler Method) - (1) MemberController
요청에 필요한 Member 정보
- name
- phoneNumber
MemberController
package com.codestates.member;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping(value = "/v1/members", produces = {MediaType.APPLICATION_JSON_VALUE})
public class MemberController {
@PostMapping
public String postMember(
@RequestParam("email") String email,
@RequestParam("name") String name,
@RequestParam("phone") String phone) {
System.out.println("email = " + email);
System.out.println("name = " + name);
System.out.println("phone = " + phone);
String response = "{" +
"\"email\":\"" + email + "\"," +
"\"name\":\"" + name + "\"," +
"\"phone\":\"" + phone + "\"" +
"}";
return response;
}
@GetMapping("/{member-id}")
public String getMember(@PathVariable("member-id") long memberId) {
System.out.println("memberId = " + memberId);
// not implementation
return null;
}
@GetMapping
public String getMembers() {
System.out.println("MemberController.getMembers");
// not implementation
return null;
}
}
produces
- 클래스 레벨의 @RequestMapping에 추가된 옵션
- 응답 데이터를 어떤 미디어 타입으로 클라이언트에게 전송할지 설정
- {MediaType.APPLICATION_JSON_VALUE} : JSON 형식으로 전송하겠다는 의미
- 이 값을 설정하지 않으면 현재 위의 코드에서는 JSON 형식의 데이터를 응답으로 전송하지 않고, 문자열 자체를 전송한다.


@RequestParam
- 핸들러 메서드의 파라미터 종류 중 하나
- 클라이언트 쪽에서 전송하는 요청 데이터를 다음의 형식으로 전송하면 이를 서버 쪽에서 전달 받을 때 사용하는 애너테이션
- 쿼리 파라미터(Query Parameter or Query String)
EX) localhost:8080/v1/members?email=mignon@email.com&name=minhyeong&phone=010-0000-0000 - 폼 데이터(form-data)
- x-www-from-urlencoded
- 쿼리 파라미터(Query Parameter or Query String)
POST 리턴 값
- postMember() 핸들러 메서드의 현재 리턴 타입은 String
- 클라이언트 쪽에서 JSON 형식의 데이터를 전송 받아야 하므로 응답 문자열을 JSON 형식에 맞게 작성한 상태
-> produces 옵션 설정으로 인해 JSON 형식으로 바뀌어 전달된다. - 일반적으로 데이터 생성 후 클라이언트 쪽으로 생성한 데이터를 리턴해주는 것이 관례
{member-id}
- 회원 식별자를 의미
- 클라이언트가 요청을 보낼 때 URI에서 이 부분을 어떤 값으로 지정하느냐에 따라 동적으로 바뀌게 된다.
@PathVariable
- 핸들러 메서드의 파라미터 종류 중 하나
- @GetMapping("/{member-id}") 에서 지정된 중괄호 ({}) 안의 문자열과 동일해야 한다.
- 두 문자열이 다를 경우 MissingPathVariableException 발생
- EX) GET, localhost:8080/v1/members/1
핸들러 메서드(Handler Method) - (2) OrderController
package com.codestates.order;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping(value = "/v1/orders", produces = MediaType.APPLICATION_JSON_VALUE)
public class OrderController {
@PostMapping
public String postOrder(
@RequestParam("memberId") long memberId,
@RequestParam("coffeeId") long coffeeId
) {
System.out.println("memberId = " + memberId);
System.out.println("coffeeId = " + coffeeId);
String response = "{" +
"\"email\":\"" + memberId + "\"," +
"\"phone\":\"" + coffeeId + "\"" +
"}";
return response;
}
@GetMapping("/{order-id}")
public String getOrder(@PathVariable("order-id") long orderId) {
System.out.println("orderId = " + orderId);
// not implementation
return null;
}
@GetMapping
public String getOrders() {
System.out.println("OrderController.getOrders");
// not implementation
return null;
}
}
Practice Project - 커피 주문 애플리케이션
Additional Keyword
'Spring' 카테고리의 다른 글
| HTTP 요청/응답에서의 DTO(Data Transfer Object) (0) | 2023.04.17 |
|---|---|
| Rest Client, RestTemplate (0) | 2023.04.17 |
| [Spring MVC] API 계층 (Prac Project - 2. ResponseEntity, Header) (0) | 2023.04.16 |
| Spring MVC의 동작 방식과 구성 요소 (0) | 2023.04.14 |
| Spring MVC 란? (0) | 2023.04.14 |
블로그의 정보
Mignon'S Dev Log
mignon25