![[인프런 워밍업 클럽 1기/BE] 첫번째 발자국](https://cdn.inflearn.com/public/files/blogs/a0e1d58c-5948-42be-bcad-6d5b7a4fe22c/썸네일.png)
[인프런 워밍업 클럽 1기/BE] 첫번째 발자국
인프런 워밍업 클럽 1기 첫번째 발자국을 찍으며..
이 스터디를 시작하게 된 동기는 직접 찾은 것은 아니고 친구의 추천으로 시작하게 되었다.
공부를 해보지 않았던 분야는 아니지만, 성격상 동기부여 될 것이 있으면 좀 더 공부를 열심히 할 수 있을 것 같다는 생각이 들었던 것 같다. 그리고 마침 오래되어 까먹기도 많이 한 것 같아 다시 한 번 상기하면 좋을 것 같았다.
이번 스터디로 공부에 대한 마음을 다시 한 번 잡고, 계획적으로 공부하는 습관을 기르기에 좋을 것 같다는 생각에 열심히 해보려 첫번째 발자국을 남긴다.
섹션 1. 생애 최초 API 만들기
어노테이션
마법같은 일(설정 등)을 자동으로 해줌
@SpringBootApplication : 스프링을 실행시킬 때 필요한 다양한 설정들을 자동으로 해줌
서버
컴퓨터가 특정 기능을 수행해준다.
그래서 컴퓨터 자체를 서버라고도 함
서버에 요청을 할 땐 인터넷(네트워크)으로 하게 됨
네트워크
현실세계에는 컴퓨터별 고유 주소(ip)가 존재
인터넷을 통해 데이터를 주고 받음
port : 특정 port를 사용하는 프로그램은 반드시 하나
Domain name : ip주소는 외우기 어려우니 ‘이름’을 쓰는것
⇒ 이러한 체계를 DNS(Domain Name System)이라함
HTTP(TyperText Transfer Protocol)
데이터를 주고 받는 표준. protocol : 표준/약속
GET : HTTP Method, 요청을 받는 컴퓨터에게 데이터를 달라고하는 것
POST : 요청을 받는 컴퓨터에게 요청하는 행위, 원하는 자원을 적어줌. 실제 저장할 정보가 포함됨,
행위와 자원은 HTTP 요청 전 약속되어있어야함HTTP 요청을 받는 컴퓨터와 프로그램 정보
Http Method + path + Query(GET) OR Body(POST)
PUT : 데이터를 수정하라(Body) / DELETE : 데이터 삭제하라(Query)
HTTP 요청 문법
(첫줄) 메소드 패스 쿼리 + HTTP 버전
(다음 줄) 헤더(여러줄 가능)
(한줄띄고 그다음 줄) 바디(여러줄 가능)
HTTP 응답
정상 처리되었다면 200 OK(상태코드)를 보낸쪽에 보냄
응답에는 추가 정보(바디)를 담을 수도 있음
300 - 다른 곳으로 옮겨라, 404 - 요청한 것찾을 수 없다, 500 - 내부에 문제가 생겼음
요청에 대한 응답을 제공(serve)한 컴퓨터가 바로 서버
요청을 한 컴퓨터가 Client(고객)
문법
(첫줄) 상태코드
(여러줄) - 헤더
한 줄 띄기
(여러 줄) - 바디
API(Application Programming Interface : 규칙)
정해진 약속을 하여 특정 기능을 수행하는 것
클라이언트와 서버가 HTTP를 주고 받으며 기능을 동작하는데 정해진 규칙을 API라 함
URL(Uniform Resource Locator)
주소창
@RestController
이 클래스를 API의 진입지점으로 만들어 줌
그 안에 메소드를 만들어서 그걸 API가 사용하게끔 만들어줄 수 있음
@GetMapping
api의 GET
@RequestParam
쿼리라고 명시
주어지는 쿼리를 함수 파라미터에 넣음
@RequestParam을 제거하고 클래스로 대체할 수 있음
DTO(Data Transfer Object) 역할을 한 것임
POST API => HTTP Body를 이용한다.
이 때 사용되는 문법이 "JSON"
JSON(JavaScriptBojectNotation) : 객체 표기법
{ “name” : “최태현”, “age” : 99, “dogs” : [”코코”, “초코”], “house” : { ”address” : “서울” } }
한 Controller Class에 여러 API 추가 가능
@PostMapping 어노테이션 사용
@RequestBody : HTTP Body로 들어오는 JSON을 객체로 변경해준다.
이 때 객체의 필드이름과 JSON key의 이름이 같아야 함
Controller에서 getter가 있는 객체를 반환하면 JSON이 된다.
public class Fruit { public String getName() { return name; } public long getPrice() { return price; } }
이게 가능한 이유는 @RestController가 붙어있기에 가능하다.
섹션2. 생애 최초 Database 조작하기
테이블 만들기
crate table [테이블 이름] (
[필드1 이름] [타입] [부가조건],
[필드2 이름] [타입] [부가조건],
...
primary key([필드이름])
);
MySQL 타입 - 정수타입
tinyint : 1바이트 정수
int : 4바이트 정수
bigint : 8바이트 정수
실수타입
double : 8바이트 정수
decimal(A, B) : 소수점을 B개 가지고 있는 전체 A자리수 실수
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
위의 SQL이 DDL(Data Definition Language)
아래는 DML(Data Manipulation Language)
조회 Query
select * from fruit where id = 1 and price <= 2000;
select * from fruit where id = 1 or price <= 2000;
select * from fruit where price BETWEEN 1000 AND 2000;
select * from fruit where name IN ('사과', '수박');
select * from fruit where name NOT IN ('사과', '수박');
업데이트 Query
update fruit set price = 1500 where name = '사과';
where 조건을 주지 않고 실행할 수 있으나, 모든 경우를 모두 변경할 수 있으니 조심해야 함
삭제 Query
delete from fruit where name = '사과';
where 조건을 붙이지 않으면 모든 데이터가 삭제됨. 주의필요
우리의 스프링 서버가 MySQL DB에 접근하게 하자
application.yml 파일에 DB 관련 설정을 적어서 가능
private final JdbcTemplate jdbcTemplate;
public UserController(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
jdbcTemplate을 이용해 SQL을 쓸 수 있다.
생성자를 만들어 jdbcTemplate을 파라미터로 넣으면, 자동으로 들어간다.jdbcTemplate.update() 는 INSERT/UPDATE/DELETE 쿼리에 모두 사용할 수 있다.
첫 파라미터로 sql을 받고, ?를 대신할 값을 차례로 넣으면 된다.
return jdbcTemplate.query(sql, new RowMapper<UserResponse>() { @Override public UserResponse mapRow(ResultSet rs, int rowNum) throws SQLException { long id = rs.getLong("id"); String name = rs.getString("name"); int age = rs.getInt("age"); return new UserResponse(id, name, age); } });
RowMapper : SQL 쿼리결과를 <>안에 있는 타입으로 변경시켜주는 역할하는 함수
람다를 사용해서 간단하게 변경할 수 있었음
HTTP Method PUT/DELETE
jdbcTemplate.update()
는 sql의 업데이트가 아니라 데이터에 변화가 있는걸 말함없는 유저를 업데이트/삭제하려 해도 200 OK가 나오는 게 문제!
자바에선 Exception/Throw로 예외를 던져 처리할 수 있었음.
스프링에서 매핑된 함수가 throw 에러를 하면 200 OK 대신 500 Internal Server Error가 나온다.
⇒ 데이터 존재 여뷰를 확인하고 예외를 던지면 되겠다
jdbcTemplate.query()
를 사용하면 반환값이 List로 감싸진다.
섹션3. 역할의 분리와 스프링 컨테이너
Clean Code는 왜 중요한가?
현업에서 코드를 읽고 조금 변경하거나 조금의 새 기능을 추가하는 일이 더 많다.
그렇기에 코드를 읽는 것을 피할 수 없다. 잘 읽을 수 있도록 하는 능력을 키우는 것도 중요하다.
내가 다른 사람의 코드를 읽듯이 다른 사람도 내 코드를 읽게되므로
나 또한 가독성이 좋은 코드를 작성하는 것도 중요하다.
왜 한 Controller에서 모든 기능을 구현하면 안될까?
<Clean Code>
함수는 최대한 작게 만들고 한 가지 일만 수행하는 것이 좋다.
클래스는 작아야하며 하나의 책임만을 가져야 한다.
반대된 다면 문제가 될 이유
함수를 동시에 여러 명이 수정할 수 없다
그 함수를 읽고 이해하는 것이 어렵다
함수의 일부분을 수정하더라도 함수 전체에 영향을 미칠 수 있어, 수정을 함부로 하기 어렵다.
너무 큰 기능이므로 테스트하기 어렵다.
종합적인 유지보수성이 매우 떨어진다.
Controller의 함수 1개가 하고 있던 역할
API 진입지점
현재 유저가 있는지 확인 후 예외처리
SQL을 사용하여 DB와 통신
Controller - API, HTTP 관련 역할 담당, Service를 사용
Service - 분기 처리, 로직 담당, Repository를 사용
Repository - DB와의 접근 담당
이러한 것을 Layered Architecture라고 한다.
※ 트러블슈팅
강의내용은 spring boot 2.x버전과 java 11사용으로 시작되었으나,
강의 시작 기준 spring initializr 기준 spring boot 3.x 버전과 java 17 버전을 사용할 수 밖에 없었음spring boot 3.2.5 + java 17 버전 연동(?) 문제
(기존 java-home이 java 11이었고, spring boot 3.x 버전부턴 java 17을 꼭 사용해야 해서 발생한 오류)
intellij 프로젝트 구조에서 java version을 변경하고, 시스템 환경변수에서
java home을 17버전으로 변경하여 해결
mysql workbench safe mode 해제
@RequestBody에 매핑되는 DTO는 왜 빈 생성자가 필요한가
과제1. 어노테이션을 사용하는 이유(효과)는 무엇일까?
https://slime-feels-660.notion.site/acb06609050b490a8d1de99c6395e8dd?pvs=4
지금까지 어노테이션들을 너무 자연스럽게 쓰다보니 왜 쓰는지나 개념적인 부분을 생각하지 않고 너무 편해서 기능만 알고 쓴 것 같았는데 조사하다보니 단순 어노테이션이라는 키워드 하나에도 공부할 수 있는 부분이 상당히 많고 깊었다.
앞으로도 단순히 사용법만 알고 기능을 사용하기보다 왜? 라는 것에 초점을 맞춰 공부해야 한다는 생각이 들었다.
과제2. API 만들기
https://slime-feels-660.notion.site/14c2b5efc21c46cd9ec46124704b31ea?pvs=4
2-1, 2-2 과제를 할 때는 생각보다 금방 했는데, 2-3번 과제를 할 때 다 만들어놓고 해결되지 않는 것을 이해를 못했다.
구글링을 통해 결국 이유를 찾았지만 쉽다 생각한 것에도 또 무언가 있었다. 얕게 공부하기보다 깊게 공부할 수 있도록 해야겠다는 마음을 다시 먹게 만들어 준 과제같았다.
과제3. 자바의 람다식은 왜 등장했을까?
람다식과 익명 클래스는 어떤 관계가 있을까?
람다식의 문법은 어떻게 될까?
https://slime-feels-660.notion.site/742bd212b32e4830b6fea014dc70c443?pvs=4
람다식을 사실 많이 쓰진 않은 것 같다. 익숙한 걸 쓴다 해야할까 쓰면 코드량이 줄고 여러 기능들이 추가되지만 자연스럽게 코딩을 하다보면 편한 방법을 쓰게 된다. 추가적으로 스터디를 해서 내 익숙한 코딩방법을 좋은 방법으로 교정하는 작업이 필요하겠다는 생각을 하게했다.
마무리
1주를 돌아보며 생각보다 시간이 부족하다. 발자국을 위해, 복습을 위해 내용을 노션에 적으면서 수강을 하니 이 정도 시간이 들겠지 하고 계획한 것보다 시간을 더 쓰게 됐었다. 시간이 있는 날은 여유가 있네 생각하고 바로 쉬는 것보다 조금 더 예습을 해두는 게 공부하기로 계획한 것을 밀리지 않고 계속 해낼 수 있을 것 같아 그렇게 해보려 한다.
아, 그리고 실수로 5/3 특강을 날짜를 착각해서 시간을 놓치게 되었는데 너무 아쉽고 17일날에는 꼭 알람을 해놓고 들어야겠다.
공부를 하며, 강의를 들으며 더 깊게 공부하고 싶은 것들이 종종 보였는데, 그런 것들도 키워드를 모아 시간을 내 공부하여 궁금한 것들을 채워나가야겠다.
댓글을 작성해보세요.