[인프런 워밍업 클럽 1기/BE] 첫번째 발자국

[인프런 워밍업 클럽 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와의 접근 담당

image

  • 이러한 것을 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일날에는 꼭 알람을 해놓고 들어야겠다.
공부를 하며, 강의를 들으며 더 깊게 공부하고 싶은 것들이 종종 보였는데, 그런 것들도 키워드를 모아 시간을 내 공부하여 궁금한 것들을 채워나가야겠다.

 

댓글을 작성해보세요.