인프런에서 주최하는 Warming-up 클럽 0기 백엔드 스터디에 참여하고 있다.
스터디에 참여하면서 배우게 된 내용을 전체적으로 정리하고, 참여하면서 느낀 부분을 회고해 보고자 한다.
(1) 2일 차 : 2024-02-20(Tue)
1. POST 방식에서 요청 데이터를 어떻게 받을까?
(1) GET 메서드의 경우 요청 URL의 쿼리 파라미터를 통해 데이터를 받는다는 것을 알 수 있었다 그렇다면 POST 메서드의 경우 어떻게 데이터를 받을 수 있을까?
(2) POST에서는 데이터를 GET 방식과 다르게 HTTP Request Body에서 확인한다. 컨트롤러의 메서드에서 Body 부분을 확인하고 필요한 데이터를 얻어오게 된다.
(3) 이때 주고받는 방식은 대표적으로 JSON(JavaScript Object Notation) 형식을 많이 사용한다.
2. JSON(Javascript Object Notation)
2-1. 기본적인 JSON
(1) JavaScript 객체 문법으로 구조화된 데이터를 표현하기 위한 문자 기반의 데이터 포맷이다.
(2) 속성: 값 타입으로 이루어져 있다.
(3) 형식은 아래와 같다.
{
"name": "userA",
"age": 20
}
(4) 각각의 속성들은 ,(Comma)로 구분된다.
2-2. JSON의 value 값으로 또 다른 JSON이 올 수 있다.
{
"name": "userA",
"age": 20,
"house": {
"address": "서울",
}
}
2-3. 결론
(1) POST 요청에서 데이터를 전달하는 방법은 HTTP Message 내부 Body 영역에 일반적으로 JSON 형태의 데이터를 담아 전송하게 되고 서버에서 받은 JSON 형식의 데이터는 서버에서 파싱해서 필요한 작업을 수행하거나 저장하는 데 사용될 수 있다.
3. HTTP API(POST) 코드 작성 및 테스트
// DTO : CalculateMultiplyRequestDto
@Getter
public class CalculateMultiplyRequestDto {
private int number1;
private int number2;
public CalculateMultiplyRequestDto(int number1, int number2) {
this.number1 = number1;
this.number2 = number2;
}
}
// Controller : CalculatorController
@RestController
public class CalculatorController {
@GetMapping("/add")
public int addTwoNumbers(CalculateAddRequestDto request) {
return request.getNumber1() + request.getNumber2() + request.getNumber3();
}
@PostMapping("/multiply")
public int multiplyTwoNumbers(@RequestBody CalculateMultiplyRequestDto request) {
return request.getNumber1() * request.getNumber2();
}
}
3-1. 어노테이션 확인 : @RequestBody
(1) 클라이언트에서 POST 방식으로 요청 메서드가 온 경우, HTTP Message 내부 Request body에 존재하는 JSON 형식의 데이터를 파싱해서 객체 형태로 변환하는 역할을 수행하는 어노테이션이다.
(2) 위의 코드에서는 HTTP Request Body로 들어오는 JSON 데이터를 파싱해서 CalculateMultiplyRequestDto로 변환해서 해당 객체의 내부 값을 사용하는 것을 알 수 있다.
3-2. Postman에서의 결과 확인
(1) Body에 JSON 형식의 데이터를 넣어서 요청을 보낸 후 정상적인 곱셈 결과를 반환받은 것을 확인할 수 있다.
3-3. 확인 가능한 점
(1) 하나의 컨트롤러에서 API를 반환하기 위한 여러 가지 메서드를 만들 수 있다.
4. 회원 엔티티(Entity) 개발
4-1. 스프링 프로젝트에서 @RestController 어노테이션이 적용된 클래스의 경우 JSON 형태의 데이터를 반환할 수 있도록 설계되어 있다.
(1) 현재 많은 웹 애플리케이션은 REST API 아키텍처를 기반으로 통신하고 있고 스프링에서도 이러한 REST API의 일관성을 지키려고 하고 있다.
(2) 따라서 스프링 기반 프로젝트를 하고 있다면 JSON 기반 데이터를 처리하기 위해서 스프링이 Jackson 라이브러리를 내부적으로 사용하며, @RestController 사용 시 HTTP 응답 결과를 JSON 형태로 파싱하여 HTTP 응답 바디에 넣어서 전송하기 때문에 기본적으로 JSON 형식으로 데이터를 응답할 수 있는 것이다.
4-2. User.java
@Getter
public class User {
private String name;
private Integer age;
public User(String name, Integer age) {
/** 회원의 이름은 공백일 수 없다 */
if (name == null || name.isBlank()) {
throw new IllegalArgumentException(String.format("잘못된 회원 이름 name(%s)이 입력되었습니다.", name));
}
this.name = name;
this.age = age;
}
}
(1) 회원의 이름으로 공백이 들어오는 경우 IllegalArgumentException 예외를 발생시키도록 코드 작성
4-3. UserListDto.java, UserController.java
// UserDtoList.java
@Getter
public class UserListDto {
private long id;
private String name;
private Integer age;
public UserListDto(long id, String name, Integer age) {
this.id = id;
this.name = name;
this.age = age;
}
}
// UserController.java
@RestController
public class UserController {
private final List<User> users = new ArrayList<>();
@GetMapping("/user")
public List<UserListDto> getAllUsers() {
List<UserListDto> response = new ArrayList<>();
for (int i = 0; i < users.size(); i++) {
response.add(new UserListDto(i + 1, users.get(i).getName(), users.get(i).getAge()));
}
return response;
}
@PostMapping("/user")
public void saveUser(@RequestBody UserCreateRequest request) {
users.add(new User(request.getName(), request.getAge()));
}
}
5. Section 1 정리
(1) 스프링 프로젝트 시작 방법, 구조, 실행 방법
(2) 네트워크, IP 주소, 도메인 네임, 포트 번호, HTTP Request/Response 구조, 클라이언트-서버 구조, 기본적인 API 개념들 학습
(3) Spring Boot 기반으로 기본적인 GET, POST API 설계 방법
5-1. 지금까지 설계한 API의 문제점
(1) 애플리케이션을 내리게 되면 기존 데이터가 삭제된다. (DBMS 부재)
(2) 이 부분에 대한 해결이 필요하다.
5-2. 데이터가 모두 사라지지 않게 하려면 어떻게 해야 할까?
- 이를 이해하기 앞서 컴퓨터의 주요 하드웨어에 대한 이해가 필요하다.
(1) CPU (프로세서)
- 산술 연산 수행
(2) RAM (메모리)
- 연산 중간에 필요한 내용들을 잠시 빠르게 저장할 수 있는 저장 장치(휘발성)
(3) DISK
- 사용자가 데이터를 영구적 또는 반영구적으로 저장할 수 있는 저장 장치(비휘발성)
5-3. 서버를 실행시켜서 API를 동작시키기까지 발생하는 일 (데이터베이스를 사용하지 않는 경우)
(1) 개발된 서버 정보는 디스크에 저장되어 있다.
(2) 서버를 실행 시 디스크에 저장된 정보가 RAM으로 로드된다.
(3) API 실행 시 프로세서와 RAM(메모리)을 거쳐가며 프로세서에 의한 연산이 수행된다.
(4) 그 결과, API 처리 결과는 메모리에 로드되어 있다.
(5) 이 상황에서 서버 프로그램을 내리게 되면 (종료 시) 모든 정보는 사라지게 된다.
(6) 그렇기 때문에 서버를 재시작하면 기존에 메모리에서 유지했던 정보는 이미 사라졌기 때문에 보이지 않게 된다.
(7) 이러한 이유로, 서버 애플리케이션을 개발할 때 데이터베이스가 필요하다.
6. 데이터베이스(Database, DB)
6-1. RDBMS(Relational Database Management System)
(1) 데이터베이스는 어떠한 규칙과 구조에 따라 체계화된 데이터의 집합이라고 볼 수 있으며 RDB는 로우와 컬럼의 구조로 데이터를 조작하고 관리할 수 있는 관계형 데이터베이스를 말한다. 대표적으로 MySQL이 있다.
6-2. SQL(Structured Query Language)
- 쿼리라고도 불리며 관계형 데이터베이스 시스템처럼 구조화된 데이터를 조회하고 조작할 때 사용되는 데이터 처리 언어이다.
6-3. MySQL에 접근하는 방법 - IntelliJ IDEA Ultimate 버전을 사용하는 경우
(1) 아래처럼 인텔리제이 우측 메뉴에서 Database → (+) new 클릭
(2) Data Source → MySQL 선택
(3) Data Sources and Drivers 메뉴에서 User, Password를 입력하고 하단의 테스트 커넥션이 성공한다면 접속이 가능한 상태이다.
6-4. MySQL에 접근하는 방법 - 터미널에서 데이터베이스 접근 (Mac OS 기준)
(1) Command : mariadb 또는 mysql -u root -p
(2) 패스워드가 설정되어 있다면 입력 후 엔터
(3) 접속 성공 시 아래와 같이 확인 가능하다.
7. 개인 회고
(1) 보통 개발할 때 Controller, Service, Repository로 각 계층별로 역할을 명확히 하여 구분하는 것이 일반적이다.
(2) 위의 회원 API를 개발할 때 데이터베이스를 전혀 사용하지 않고 메모리에서 동작하도록 자바 컬렉션을 사용해서 데이터를 저장하고 조회했는데 평소 데이터베이스에서 CRUD를 하다 보니 자바 컬렉션에서 처리하는 코드들이 조금 낯설게 느껴진 것 같다.
(3) 해당 코드들을 보고 데이터베이스를 추가해서 코드를 개선하고 싶다는 생각이 많이 든다.
(4) 다음 학습 내용도 잘 정리해서 기록해 보려고 한다.
※ 해당 포스팅에 대해 내용 추가가 필요하다고 생각되면 기존 포스팅 내용에 다른 내용이 추가될 수 있습니다.
개인적으로 공부하며 정리한 내용이기에 오타나 틀린 부분이 있을 수 있으며, 이에 대해 댓글로 알려주시면 감사하겠습니다!
'기록, 회고 > InFlearn Warming-up 0기 BE' 카테고리의 다른 글
[3일 차] - 내용 정리, 개인 회고 (0) | 2024.02.20 |
---|---|
[2일 차] - 과제 수행 : GET, POST API 설계 (4) | 2024.02.19 |
[1일 차] - 과제 수행 : Spring(Java)에서 Annotation 사용하기 (1) | 2024.02.18 |
[1일 차] - 내용 정리, 개인 회고 (2) | 2024.02.18 |
[0일 차 OT] 일간 내용 정리, 회고 (2024-02-16) (0) | 2024.02.16 |
댓글