[인프런 워밍업 클럽 0기] BE 2일차 과제

김영훈·2024년 2월 20일
0
post-thumbnail

<과제 내용>

진도표 2일차와 연결됩니다.

우리는 GET API와 POST API를 만드는 방법을 배웠습니다. 👍 추가적인 API들을 만들어 보며 API 개발에 익숙해져 봅시다!

문제 1

두 수를 입력하면, 다음과 같은 결과가 나오는 GET API를 만들어 보자!

  • path : /api/v1/calc이다.
  • 쿼리 파라미터 : num1, num2
{
"add": 덧셈결과,
"minums": 뺄셈결과,
"multiply": 곱셈결과
}

예시

GET /api/v1/calc?num1=10&num2=5

{
"add": 15,
"minums": 5,
"multiply": 50
}

MyAPI 1

  • path : /api/v1/calc이다.
  • 쿼리 파라미터 : num1, num2

  • Controller

@RequiredArgsConstructor
@RestController
public class APIController {
	private final APIService apiService;
    
    @GetMapping("/api/v1/calc")
    public ResponseEntity<CalcResponse> calcResponse(@RequestParam int num1, @RequestParam int num2) {
        CalcEntity calcEntity = apiService.calculatorService(new CalcRequest(num1, num2));
        CalcResponse calcResponse = new CalcResponse(calcEntity);
        return ResponseEntity.ok() 
                .body(calcResponse); //HttpResponse(200)과 함께 반환
    }
}
  • DTO(Request)

@NoArgsConstructor
@AllArgsConstructor
@Getter
public class CalcRequest {
    private int num1;
    private int num2;

    public CalcEntity toEntity() { 
        return CalcEntity.builder() // builder를 통해 Entity로 변환
                .num1(num1)
                .num2(num2)
                .build();
    }
}
  • Service

@Service
public class APIService {
  public CalcEntity calculatorService(CalcRequest request) {
          return request.toEntity(); 
      }
}
  • Entity

@Getter
@NoArgsConstructor
public class CalcEntity {
    private int num1;
    private int num2;

    @Builder
    public CalcEntity(int num1, int num2) {
        this.num1 = num1;
        this.num2 = num2;
    }

}
  • DTO(Response)

@Getter
public class CalcResponse {
    private final int add;
    private final int minus;
    private final int multiply;

    public CalcResponse(CalcEntity calcEntity) { // 생성자로 Entity를 받아서 add, minus, multiply값만 전달함 
        this.add = calcEntity.getNum1() + calcEntity.getNum2();
        this.minus = calcEntity.getNum1() - calcEntity.getNum2();
        this.multiply = calcEntity.getNum1() * calcEntity.getNum2();
    }
}
  • 실행 결과(PostMan)

    상태 코드Body 둘 다 정상적으로 받아온다.

  • View

<h3>MyAPI 1</h3>
<div class="col-sm-8" style="background-color: ivory">
	<br>
	<label for="num1">num1 : </label> <input type="number" id="num1" class="form-control" value="0"><br>
	<label for="num2">num2 : </label> <input type="number" id="num2" class="form-control" value="0"><br>
	<button class="btn btn-primary" th:onclick="calcBtn()">GET</button>
	//onclick시 function calcBtn() 실행
	<br>
	<br>
</div>
	<br>
	<div class="col-sm-8" style="background-color: ivory">
		<span id="calc">
		<h3 class="badge badge-light text-danger">실행 결과 : </h3><br>
		</span>
	</div>
  • API.js

function calcBtn() {
    let num1 = document.getElementById('num1').value; 
    let num2 = document.getElementById('num2').value;
	//Id로 value조회
    fetch(`/api/v1/calc?num1=${num1}&num2=${num2}`, { 
        method: 'get' 
    }) // GET방식, pathurl에 num1, num2 담아서 넘김
        .then(response => {
            if (!response.ok) //HttpStatus가 200 ok가 아닐경우
                throw new Error('서버로부터 값을 받아오지 못했습니다(calc)')
            return response.json(); //response를 json형태로 변환
        })
        .then(data => { //{"add": ?, "minus": ?, "multiply": ?}
            const addValue = data.add;
            const minusValue = data.minus;
            const multiplyValue = data.multiply; //key:value 조회
            $("#calc").html( 
                `
    <h3 class="badge badge-light text-danger">실행 결과 : </h3><br>
    {<br>
    <span class="text-success">"add"</span>: <span class="text-danger">${addValue},</span><br>
    <span class="text-success">"minus"</span>: <span class="text-danger">${minusValue},</span><br>
    <span class="text-success">"multiply"</span>: <span class="text-danger">${multiplyValue}</span><br>
    }
    `
            );
        }) 
        .catch(error => {
            alert('/api/v1/calc 오류 \n입력값을 확인해주세요.') 
        })
}
  • 실행 결과


문제 2

날짜를 입력하면, 몇 요일인지 알려주는 GET API를 만들어 보자!
path와 쿼리 파라미터는 임의로 만들어도 상관없다.

예시

GET /api/v1/day-of-the-week?date=2023-01-01

{
"dayOfTheWeek": "MON",
}

MyAPI 2

  • path와 쿼리 파라미터는 임의로 만들어도 상관없다.

  • Controller

@GetMapping("/api/day-of-the-week") //@DateTimeFormat으로 yyyy-MM-dd 형태로 변환해서 받는다
    public ResponseEntity<DayOfWeekResponse> dateResponse(@RequestParam("date") @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate localDate) {
          DayOfWeek dayOfWeek = apiService.dayOfWeekService(localDate);
          DayOfWeekResponse dayOfWeekResponse = new DayOfWeekResponse(dayOfWeek);
          return ResponseEntity.ok()
                  .body(dayOfWeekResponse);
    }
  • Service

@service
public class APIService{
  public DayOfWeek dayOfWeekService(LocalDate localDate) {
          return localDate.getDayOfWeek(); //localDate값을 DayOfWeek로 변환해서 반환
      }
}
  • DTO(Response)

@Getter
public class DayOfWeekResponse {
    private final String dayOfTheWeek;

    public DayOfWeekResponse(DayOfWeek dayOfTheWeek) { //DayOfWeek -> String 변환(SHORT: Sunday->Sun)
        this.dayOfTheWeek = dayOfTheWeek.getDisplayName(TextStyle.SHORT, Locale.US).toUpperCase();  
        //예시가 대문자였으니 toUpperCase()
    }
}
  • 실행 결과(PostMan)

  • View

<h3>MyAPI 2</h3>
	<div class="col-sm-8" style="background-color: ivory">
	<br>
	<label for="day_of_week">
		<input type="date" class="form-control" id="day_of_the_week">
		</label>
		<br>
		<br>
		<button class="btn btn-primary" th:onclick="day_of_the_week_Btn()">GET</button>
		<br> //버튼을 누르면 function day_of_the_week_Btn(){} 실행하고 
        <br> //input 값 가져올 예정
	</div>
	<br>
	<div class="col-sm-8" style="background-color: ivory">
		<span id="day_of_week">
		<h3 class="badge badge-light text-danger">실행 결과 : </h3><br>
		</span>
	</div>
  • API.js

function day_of_the_week_Btn() {
    let selectedDate = document.getElementById('day_of_the_week').value;
  //input 값 얻어오기
    fetch(`api/day-of-the-week?date=${selectedDate}`, {
        method: 'get' //GET방식, url로 selectedDate넘겨준다. 
    })
        .then(response => {
            if (!response.ok) // response != 200 ok
                throw new Error('서버로부터 값을 받아오지 못했습니다(dayOfTheWeek)')
            return response.json(); //json화
        })
        .then(data => { // {"dayOfTheWeek": "MON"}
            const dayOfTheWeek = data.dayOfTheWeek;
            $("#day_of_week").html(
                `
                <h3 class="badge badge-light text-danger">실행 결과 : </h3><br>
                {<br>
                <span class="text-success">"dayOfTheWeek" : "${dayOfTheWeek}"</span><br>
                }
                `
            )
        })
        .catch(error => {
            alert("/api/day-of-the-week 오류\n입력값을 확인해주세요.")
        })

}
  • 실행 결과


문제 3

여러 수를 받아 총 합을 반환하는 POST API를 만들어 보자!
API에서 받는 Body는 다음과 같은 형태이다.
(HINT : 요청을 받는 DTO에서 LIST를 갖고 있으면 JSON의 배열을 받을 수 있습니다.)

{
"numbers": [1,2,3,4,5]
}

반환결과

15

⚠️ 주의
반환 결과는 JSON이 아닙니다!
함수에서 String 혹은 Integer를 반환하면, API 결과가 JSON으로 나가지 않고, 단순한 값으로 나가게 됩니다.
POST MAN과 같은 API 테스트 툴을 이용해 한 번 확인해보세요~😊


MyAPI 3

  • API 결과를 JSON으로 반환 X

  • Controller

@PostMapping("/api/v1/addNumbers") //Integer 반환
    public ResponseEntity<Integer> addNumber(@RequestBody AddNumberRequest addNumberRequest) { 
        Integer sum = apiService.addNumber(addNumberRequest);
        return ResponseEntity.status(HttpStatus.CREATED) // 테스트 해보고싶어서 201로 보냄
                .body(sum); 
    }
  • DTO(Request)

@Getter
public class AddNumberRequest {
    private List<Integer> numbers;
}
  • Service

@Service
public class APIService {
  public Integer addNumber(AddNumberRequest addNumberRequest) {
          return addNumberRequest.getNumbers().stream().reduce(0, Integer::sum);
      }
}
  • 실행 결과(Post Man)

    설정해둔 응답 코드 201 Created 정상적으로 출력

  • View

<h3>MyAPI 3</h3>
	<div class="col-sm-8" style="background-color: ivory">
		<br>
		<table class="table table-borderless">
			<tr>
				<td>number : {</td>
				<td></td>
			</tr>
    		<tr>
				<td colspan="2"><input type="number" class="numbers" value="0"></td>
			</tr>
			<tr>
				<td colspan="2"><input type="number" class="numbers" value="0"></td>
			</tr>
			<tr>
				<td colspan="2"><input type="number" class="numbers" value="0"></td>
			</tr>
			<tr>
				<td colspan="2"><input type="number" class="numbers" value="0"></td>
			</tr>
			<tr>
				<td colspan="2"><input type="number" class="numbers" value="0"></td>
			</tr>
			<tr>
				<td>}</td>
				<td></td>
 			</tr>
		</table>
		<button class="btn btn-primary" th:onclick="addNumbers()">POST</button>
		<br> //누르면 function addNumbers(){} 로 numbers값 전달 예정
		<br>
	</div>
  • 실행 결과


0개의 댓글