[인프런 워밍업 스터디 클럽 1기] 1주차 발자국
발자국
강의는 진도표에 맞춰 진행하였으며 회고록 또한 그에 맞춰 작성하였다.
인프런 워밍업 스터디 클럽 완주를 목표로 남은 기간동안 매일매일 꾸준히 학습하기 위해 노력하겠다.
1주차 학습 내용
DAY 1 : 서버개발을 위한 환경 설정 및 네트워크 기초
1강 : 스프링 프로젝트를 시작하는 두번째 방법
스프링 프로젝트를 시작하는 방법은 크게 2가지가 있다.
이미 만들어져 있는 프로젝트를 다운하거나 Spring initializr ( https://start.spring.io/ )를 이용해 새로운 프로젝트를 시작한다.
위의 이미지와 같은 홈페이지에 접속하여 프로젝트의 빌드툴, 이름, 서버개발에 사용할 언어, 의존성을 설정하여 시작할 수 있다.
2강 : @SpringBootApplication과 서버
@SpringBootApplication 어노테이션 : 스프링을 실행시키기 위한 다양한 설정을 자동으로 처리해 준다.
server : 어떠한 기능을 제공하는 프로그램, 프로그램을 실행시키고 있는 컴퓨터를 의미한다.
3강 : 네트워크란 무엇인가?
IP : 컴퓨터별 고유 주소
port : 여러 프로그램 중 하나만을 특정하는 것을 의미
Domain Name : 244.65.51.9 대신 spring.com 으로 표현
이러한 체계를 Domain Name System (DNS) 라고 한다.
4강 : HTTP와 API란 무엇인가?
HTTP (HyperText Transfer Protocol) : 데이터를 주고 받는 표준
Protocol : 표준, 약속
GET / portion?color=red&count=2
HOST:spring.com:3000
GET : 요청 행위 → HTTP Method
HOST : 요청을 받는 컴퓨터와 프로그램 정보
/portion : Path, HTTP 요청을 받는 컴퓨터에게 원하는 자원
? & : 구분 기호
?color=red&count=2 -> 원하는 조건, Query라고 부른다.
각 HTTP Method 마다 사용되는 것이 다르다.
GET : Query 사용 (조회)
POST : Body 사용 (생성)
PUT : Body 사용 (수정)
DELETE : Query 사용 (삭제)
API (Application Programming Interface) : 정해진 약속을 하여 특정 기능을 수행하는 것
URL (Uniform Resource Locator) : 주소창 (ex. http://spring.com:3000/porting?color=red&count=2)
5강 : GET API 개발하고 테스트하기
API를 개발하기에 앞서 API를 이루고 있는 요소들을 설계해야한다. 이를 API Specification (명세) 라고 한다.
Controller, DTO 생성과 GET API 작성 이후 만들어진 API를 Postman으로 테스트하는 실습을 진행하였다.
DAY 2 : 첫 HTTP API 개발
6강. POST API 개발하고 테스트하기
Controller, DTO 생성과 POST API 작성 이후 만들어진 API를 Postman으로 테스트하는 실습을 진행하였다.
데이터를 어떻게 받을까? → HTTP BODY를 통해 받는다.
BODY로 데이터를 어떻게 받을까? -> JSON
JSON : 객체 표기법, Map<Object, Object> 느낌
{
"name": "강성관",
"age": 26
}
JSON의 value에는 리스트, 객체 등등 다양한 타입을 받을 수 있다.
@RequestBody : HTTP Body로 들어오는 JSON을 주어진 객체로 변경해주는 어노테이션
@PostMapping("/multiply")
public int multiplyTwoNumbers(@RequestBody CalculatorMultiplyRequest request) {
return request.getNumber1() * request.getNumber2();
}
즉, HTTP Body는 CalculatorMultiplyRequest에 매핑된다.
7강. 유저 생성 API 개발
도서관 애플리케이션의 요구사항
사용자
사용자 등록
사용자 목록 조회
사용자 이름 업데이트
사용자 삭제
책
책 등록 및 삭제
사용자 책 대여
다른 사람이 그 책을 빌렸다면 빌릴 수 없다
책 반납
API 설계
Method : POST
path : /user
Body (JSON)
{ "name": String (null 불가능) "age": Integer }
결과 반환 X (HTTP 상태 200 OK이면 충분하다)
8강. 유저 조회 API 개발과 테스트
결과 반환이 JSON이다?
Controller 에서 getter가 있는 객체를 반환하면 JSON이 된다.
Id는 무엇인가?
유저별로 겹치지 않는 유일한 번호
List에 담겨 있는 유저의 순서를 id로 정하여 진행
DAY 3 : 기본적인 데이터베이스 사용법
10강. Database와 MySQL
Datebase와 Mysql의 사전 지식과 연결 방법에 대한 설명
11강. MySQL에서 테이블 만들기
//데이터베이스 만들기
create database 데이터베이스명;
//데이터베이스 목록 보기
show databases;
//데이터베이스 지우기
drop database 데이터베이스명;
//데이터베이스 안으로 들어가기
use 데이터베이스명;
//테이블 목록 보기
show tables;
//테이블 만들기
create table 테이블명 (
필드명 타입 부가조건
필드명 타입 부가조건
...
primary key (필드이름)
);
MySQL 타입 살펴보기
정수 타입
tinyint : 1 바이트 정수
int : 4 바이트 정수
bigint : 8 바이트 정수
실수 타입
double : 8 바이트 정수
decimal(A, B) : 소수점을 B개 가지고 있는 전체 A자릿수 실수 ex) Decimal(4, 2) = 12.23
문자열 타입
char(A) : A글자가 들어갈 수 있는 문자열
varchar(A): 최대 A글자가 들어갈 수 있는 문자열
날짜, 시간 타입
date : 날짜, yyyy-MM-dd
time : 시간, HH:mm:ss
datetime : 날짜와 시간을 합친 타입, yyyy-MM-dd HH:mm:ss
12강. 테이블의 데이터를 조작하기
//데이터 넣기
INSERT INTO 테이블명 (필트명, 필트명, ...) VALUES (값, 값, ...);
//데이터 조회 (* 대신 필드명을 넣을 수 있다.)
SELETE * FROM 테이블명;
//데이터 조회 필터 사용 (AND와 OR를 통해 이어붙일 수 있다.)
SELETE * FROM 테이블명 WHERE 조건;
//데이터 업데이트하기 (조건을 붙이지 않는다면 모든 데이터가 수정된다.)
UPDATE 테이블명
SET 필드명 = 값, 필드명 = 값
WHERE 조건;
//데이터 삭제 (조건을 붙이지 않는다면 모든 데이터가 삭제된다.)
DELETE FROM 테이블명 WHERE 조건;
13강. Spring 에서 Database 사용하기
스프일 서버가 MySQL DB에 접근하는 방법
application.yml 만들고 설정하기
spring:
datasource:
url: "jdbc:mysql://localhost/library"
username: "root"
password: ""
driver-class-name: com.mysql.cj.jdbc.Driver
이후, User 테이블 생성 후 기존의 실습을 진행하면서 메모리에 저장하던 유저정보를 MySQL에 저장하게 바꾸는 실습을 진행하였다.
DAY 4 : 데이터베이스를 사용해 만드는 API
14강. 유저 업데이트 API. 삭제 API 개발과 테스트
도서관 사용자 이름 업데이트
HTTP Method : PUT
HTTP Path : /user
HTTP Body (JSON)
{ "id": Long, "name": String // 변경되어야 하는 이름이 들어온다. }
결과 반환 X (HTTP 상태 200 OK이면 충분)
사용자 삭제
HTTP Method : DELETE
HTTP Path : /user
쿼리 사용
문자열 name
결관 반환 X
한가지 문제 발생 → 수정과 삭제할 때 데이터베이스에 없는 유저를 수정하거나 삭제 시 200 OK를 반환
15강. 유저 업데이트, 삭제 API 예외 처리 하기
데이터 존재 여부 확인 후 예외를 던지자!
실습 진행!
@PutMapping("/user")
public void updateUser(@RequestBody UserUpdateRequest request) {
// 해당 id를 가지고 있는 User가 있는지 확인하는 쿼리
String readSql = "SELECT * FROM user WHERE id = ?";
// 있다면 0를 가지고 있는 List 생성, 아니면 빈 List 생성,
// .isEmpty()를 이용하여 비어있다면 True 아니면 false 반환
boolean isUserNotExist = jdbcTemplate.query(readSql, (rs, rowNum) -> 0, request.getId()).isEmpty();
if (isUserNotExist) {
throw new IllegalArgumentException();
}
String sql = "UPDATE user SET name = ? WHERE id = ?";
jdbcTemplate.update(sql, request.getName(), request.getId());
}
@DeleteMapping("/user")
public void deleteUser(@RequestParam String name) {
// 해당 name를 가지고 있는 User가 있는지 확인하는 쿼리
String readSql = "SELECT * FROM user WHERE name = ?";
// 있다면 0를 가지고 있는 List 생성, 아니면 빈 List 생성,
// .isEmpty()를 이용하여 비어있다면 True 아니면 false 반환
boolean isUserNotExist = jdbcTemplate.query(readSql, (rs, rowNum) -> 0, name).isEmpty();
if (isUserNotExist)
throw new IllegalArgumentException();
String sql = "DELETE FROM user WHERE name = ?";
jdbcTemplate.update(sql, name);
}
DAY 5 : 클린코드의 개념과 첫 리펙토링
17강. 좋은 코드는 왜 중요한가?
Code는 요구사항을 표현하는 언어이고 개발자는 요구사항을 구현하기 위해 코드를 읽고 작성한다.
하지만 다른 사람이 작성하는 코드와 내가 예전에 작성해둔 코드를 다시 읽었을 때, 다시 이해하는 것은 쉬운 일이 아니다.
개발자에게 코드를 읽고 이해하는 것은 필수적이고 피할 수 없다.
그럼 코드를 봤을 때, 무엇을 하는지 알 수 없는 코드를 이해하려는 것과
어떤 동작을 하고 무엇을 원하는지 의미를 파악할 수 있는 코드를 이해하는 것은 차이가 크다는 것을 알 수 있다.
18강. Controller 3단 분리하기
기존의 Controller에 하나로 뭉쳐있는 코드를 Service와 repository로 나누는 리팩토링 과정의 실습을 진행하였다.
Controller와
1주차 과제
과제 1
질문 1. 어노테이션을 사용하는 이유 (효과) 는 무엇일까?
질문 2. 나만의 어노테이션을 어떻게 만들 수 있을까?
평소 공부하면서 어노테이션을 사용하는 이유에 대해 명확하게 알지 못했다. 과제를 통해 어노테이션의 사용 이유와 효과, 각각의 기능이 어떻게 동작하는지 알 수 있었다. 특히, 롬복을 통해 getter, setter, 생성자를 자동으로 생성하고 주입하는 기능을 알 수 있었다. 나만의 어노테이션을 만들 때, @Retention 어노테이션을 사용하여 나만의 어노테이션을 정의하고 유지한다는 것을 알게 되었다.
과제 2
API 명세를 통해 GET, POST API 만들기
자신있게 시작했던 모습은 얼마 가지 않아 헤매는 부분이 있었던 것 같다. 총 3문제 중 첫문제만 Request 파일과 Response 파일을 만들 수 있었다. 시간에 쫓겨 못한 부분이 있었다. 다음에는 시간을 가지고 좀 더 많은 고민을 하면서 완성하고 싶다.
과제 3
질문 1. 자바의 람다식은 왜 등장했을까?
질문 2. 람다식과 익명 클래스는 어떤 관계가 있을까?
람다 도입 배경이 다른 언어에 뒤쳐지지 않고 큰 데이터를 다루기 위해 병렬성 활용과 간결한 코드의 중요성이 올라 갔기 때문이다.
알지 못하고 사용했던 때보다 람다의 도입 배경을 알고 적절한 곳에 사용할 수 있을 것 같다. 람다식과 익명 클래스의 관계를 알아보며 람다는 사실 익명 클래스의 객체라는 점이 놀라웠다.