inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

[인프런 워밍업 스터디 클럽 0기_BE] 1주차 회고록 정리

dmstjd0214
0

주차 별 내용 간단 정리

 

Day1

강의

GET
/portion?color=red&count=2
Host: spring.com:3000

GET방식으로 PATH는 /portion 쿼리 스트링은 color : red , count : 2

서버는 spring.com:3000

파라미터 보내는 방식은 (키,값) 으로 되어있습니다.

 

@Getter
public class CalculatorAddRequest {
    private  final int number1;
    private  final int number2;

    public CalculatorAddRequest(int number1, int number2) {
        this.number1 = number1;
        this.number2 = number2;
    }

}

 

@RestController 
public class CalculatorController {

    @GetMapping("/add")
    public int addTwoNumbers(CalculatorAddRequest request){
        return request.getNumber1()+request.getNumber2();
    }
}

 

미션

첫번째 미션 접근 방식은 어노테이션 사용 이유와 나만의 어노테이션을 작성하는 것이였습니다.

어노테이션에 대한 내용을 파악하고 코드로 사용을 사용했지만 직접 만들어본적은 없기때문에 많이 헷갈렸던거 같습니다.

또한 어노테이션을 사용하는 이유에 대해 정확하게 정의를 내리지 못했지만 1주차 과제를 진행하며 많이 얻어갔던 것 같습니다. 나한테 들리는 왜?라는 질문에 대한 대답을 하였던 것 같아 재밌었던거 같습니다.

한가지로 아쉬웠던 점으로는 문서 작성에 대한 미숙함으로 인해 두서없이 작성되는 것같아 다음에 잘 작성해야겠다 생각했습니다.

정리 : https://silvercastle.notion.site/1-aea485f7cd5a433a8fb52715b16a81c9?pvs=4


 

Day2

강의

POST요청을 받기위해 Body에 데이터를 담아 보낸다.

Body에 데이터를 보내는 방법으로는 JSON형태로 보내면 된다.

JSON이란?

데이터를 쉽게 교환하고 저장하기 위한 표준 방법

형식은 (키 : 값) 형식으로 되어있으며 자바에 자료구조인 Map과 유사합니다.

2. 중괄호 안에 (키,값)형태로 표기 숫자는 큰따옴표가 들어가지 않으며, 속성은 쉼표로 구분합니다. 배열 작성시 위에 내용과 마찬가지로 []을 넣으면된다. JSON에 또 다른 객체를 넣고 싶다면 {}를 넣어 표현하면 됩니다.

{
   "name" : "이은성",
   "age": 1000,
   "pocket" : ["핸드폰","지갑"],
   "info" : {
     "address" : "서울",
     "phoneNum" : "010-1111-1111"
   }
}

여기서 문제점은 List에 저장하는 방식은 메모리에 저장하는 방식으로 웹서버를 재시작하는 경우, 기존에 있던 값들이 날아가는 문제가 있어 서비스 운영이 어려워집니다. 이를 해결하기 위해선 어떤 방안이 있을까요?

미션

첫번째 미션은 두 수를 입력하면 다음과 같은 결과가 나오는 GET API를 만들자

제가 설계한 방법으로는 요구사항대로 첫번째 쿼리스트링이기때문에 @RequestBody를 사용하지 않아야 된다 생각했으며, 강의에서 배운 DTO객체를 request와 response를 나눠 작업을 진행했습니다.

첫번째 문제는 크게 어렵지 않았습니다.

두번째 문제는 날짜를 입력하면 무슨 요일인지 알려주는 GET API를 만들어보는 것이였습니다.

코치님이 조언해주기를 LocalDate를 활용해보라해서 넘어오는 날짜 : yyyy-mm-dd 형식으로 받아오는것을 String으로 받아와 자바에서 지원하는 LocalDate를 활용하여 String값을 split하여 of에 넣어주는 작업을 진행 후 getDayOfWeek과 getDisplayName에 있는 메서드를 활용하여 진행했습니다.

하지만 추가적으로 LocalDate를 사용하는 방법중에 yyyy-mm-dd를 직접넣어 파싱해주는 메서드를 찾았고 그것을 활용하여 사용해봤습니다.

코치님께서 모든 과제를 확인후 String을 받지않고 직접 LocalDate를 파라미터 값으로 받아 사용하면 훨씬 코드가 깔끔해진다는 내용을 듣고 앞으로 설계할때 고려해야겠다 생각했습니다.

LocalDate나 LocalDateTime에 대해 자주 사용해보지 않았지만, 내용들을 이해하며 사용해보니 많이 와닿았습니다.

[노션] : https://silvercastle.notion.site/2-3d17d8447562464eb081c340bbfbdfc8?pvs=4

[깃허브] : https://github.com/backgom1/Inflearn_BE0_Study/tree/main/ens-library-app/src/main/java/com/group/enslibraryapp/learn/controller/example

 


Day3

강의

Day2에서 고민한 내용에 대한 답변은 데이터베이스를 활용하여 데이터를 저장하는 방식을 사용하면 좋습니다.

실무에서 회사내에서 데이터베이스를 어떤방식으로 활용하면 좋을지 고민을 많이 했고, 아직 많이 부족한 실력이라 인지하고 있습니다. 또한 RDBMS를 지금까지 MariaDB,PostgreSQL을 사용해보았고 물론 크게 다른 점은 없지만 MySQL을 활용해보는 계기가 되었습니다.

yml방식으로 데이터베이스에 필요한 정보를 가지는 명령어입니다.

아이디, 비밀번호, url, driver로 구성되어있으며, 만약 일치하지 않거나 DB서버가 죽었을경우 컴파일 과정에서 문제가 발생합니다.

저는 시작을 jdbcTemplate이 아닌 Mybatis와 JPA같은 기술스택을 먼저 사용해보고 이후로 사용을 했는데 예전 개발자님들은 상남자이며, 정말 예외에 대한 처리를 하나하나생각하기 머리가 아팠을꺼같습니다. 그리고 이전기술을 사용하니 JPA와 MyBatis와 같은 기술들이 얼마나 간편하고 좋은지에 대해 알아갔습니다.

미션

과제에 대한 내용중에 익명클래스,람다,Stream문 ,함수형 프로그래밍 @FunctionalInterface, 메소드 레퍼런스등을 정리하며 기존에 인텔리제이에서 제안 및 변환작업만 자동으로 진행했지 이게 무슨 내용인지에 대해 찾아보려 하지 않았습니다. 정말 인텔리제이는 좋은 도구지만 용도를 더 잘 알고 사용하는 것이 나중에 1000퍼 더 이해되기 쉽다를 느꼈습니다.

또한 익명클래스와 람다식에 대한 차이점과 람다식을 왜 등장했는지에 대한 내용을 정리하며, 동작원리를 이해하고 이래서 익명 클래스에 대한 불편함과 그로인해 람다를 사용하는 방법을 알았습니다. 점점 더 내안의 "왜?"를 채울 수있어서 좋았습니다.

[노션] : https://silvercastle.notion.site/3-f34ffaa6ae8147d58f24659af459bf9e?pvs=4

 


 

Day4

강의

기존에 배웠던 내용을 가지고 유저 업데이트API, 삭제 API 개발과 테스트를 진행을 해보았습니다.

 

HTTP body

{
  "id" : Long,
  "name" : String
}

HTTP Response : Void // 200 OK!

 

HTTP Method : PUT

HTTP Path : /user

@PutMapping("/user")
public void updateUser(@RequestBody UserUpdateRequest request){
String sql = "update user set name = ? where id = ?";
jdbcTemplate.update(sql, request.getName(),request.getId());
} 

 

 

HTTP Method : DELETE

HTTP Path : /user

@DeleteMapping("/user")
public void updateUser(@RequestBody UserUpdateRequest request){
String sql = "delete from user where name = ?";
jdbcTemplate.update(sql, request.getName());
} 

 

이전 강의에서 마찬가지로 코드를 sql문과 update를 활용하여 데이터베이스 변경작업을 진행했습니다.

기존에 준 웹 UI를 가지고 변경과수정 작업을 진행했습니다.

 

또한 예외처리를 배웠는데 사용자가 없을경우? 이런저런것에 대한 처리가 되어있지않아 서비스를 운영할때 큰 문제로 다가올 수 있습니다.

String readSql = "SELECT * FROM user WHERE id= ?";
boolean isUserNotExist = jdbc.query(readSql,(rs,rowNum) 0,request.getId()).isEmpty
if(isUserNotExist){
  throw new IllegalArgumentException();
}

사용자의 정보에 대해 조회를하고 만약 존재하지 않는다면 List가 공백으로 나오며 , 비어있다면 true 비어있지 않으면 false로 반환하는 코드를 작성 후 인자값 오류에 대한 예외처리를 진행했습니다. 이것말고 다른 예외처리도 생각을 꼭꼭해야합니다. 그래서 개발하기 전에 어떤 문제를 야기할지 생각한 후 코드를 개발하는것이 더 좋다 생각합니다.

 

 

하지만 Controller메서드들에 너무 많은 기능과 역할을 하고있다 생각하고 있습니다. 나중에 코드가 1000줄이상 늘어나면 보기 복잡해질 것이며, 가독성과 유지보수성이 떨어져 개발하면서 어려움을 겪을 수있습니다. 나중에 Day5의 강의의 클린코드를 통해 변경하는 작업을 진행해야겠다 생각했습니다.

 

미션

문제별로 설계 방법은 첫번째로 어떤 table을 제작해야할지, table안에 어떤 column을 생성하면 좋을지 분석 및 구현을 진행했으며, 두번째로 패키지구조를 나눠 각 메서드마다 역할분담을 해야한다 생각했습니다.

문제를 해결하면서 3번문제를 잘못 읽는바람에 시간이 소요되는 문제가 있었습니다. 항상 개발자는 요구사항에 대한 분석을 해야한다 느꼈습니다.

시간이 부족한탓에 예외처리를 완벽하게 처리를 하지 못했는데 나중에 그것도 설계해서 예외처리를 둬야겠다 생각했습니다.

[노션] : https://silvercastle.notion.site/4-9621a06cc0d24a63871a9f50e8c6cd48?pvs=4

[깃허브] : https://github.com/backgom1/Inflearn_BE0_Study/tree/main/ens-library-app/src/main/java/com/group/enslibraryapp/daliy/dayfour


Day5

강의

해당 코드는 조회하는 쿼리에 대해 대한 컨트롤러 메서드입니다. 딱 봐도 기능적 분리가 필요해보입니다.
sql문은 어떤식으로 분리하면 좋을까?라는 생각과 비지니스로직을 어디다 분리 할까 생각하다 Layered Architecture

에대해 배운 내용을 바탕으로 나눴습니다.

Controller : HTTP Body 요청을 받아 객체로 변환하는 계층

Service : 비지니스로직(현재 유저 확인)기능이 동작하기 위한 작업을 진행하는 계층

Repository : 데이터베이스와 접근 및 상호작용을 하기위해 나타나는 계층

 

UserController

    @GetMapping("/user")
    public List<UserResponseDto> getUsers() {
       return userService.getUsers();
    }

 

UserService

    public List<UserResponseDto> getUsers() {
       return userRepository.getUser();
    }

 

UserRepository

   public List<UserResponseDto> getUser() {
        String sql = "select * from user";
        return jdbcTemplate.query(sql, (rs, rowNum) -> {
            long id = rs.getLong("id");
            String name = rs.getString("name");
            int age = rs.getInt("age");
            return new UserResponseDto(id, name, age);
        });
    }

해당 3계층으로 나눠 진행했습니다! 해당 기능을 분리를 진행했으며, 이전 코드에 비해 깔끔해졌으며 나중에 코드를 추가및 변경할때 해당 계층으로 들어가 작업을 하면 됩니다.

 

미션

오랜만에 코딩테스트 문제 풀듯이 풀어 재밌었다.

첫번째방식은 기존에 긴 코드에 대한 기능에 대한 분리를 진행을 해봤습니다. 객체지향 SOLID 특징 중 SRP(단일 책임 원칙)을 생각하여 나누려고 진행했습니다. 나눈 기능에 대한 세부 동작을 나눴으며, 그로 인해 클래스를 나눠 구현하도록 설계를 진행했습니다. 또한 애매한 변수 네이밍, 메서드 네이밍에 대한 수정도 이루어지도록 생각을 했습니다.

코드를 수정후 한 걸음 더에 대한 요구사항에 대한 제 분석은

  1. 현재 코드는 1~6이지만 동적으로 변경할 수 있는 방법

  2. 주사위의 시행 횟수를 동적으로 변경하는 방법
    해당 방법 2가지를 생각했으며, 그에 따라 정적배열, for문등등을 활용하여 작업을 진행했습니다.

 

[노션] : https://silvercastle.notion.site/5-89b621e69f094263af872580ac19324c?pvs=4

[깃허브] : https://github.com/backgom1/Inflearn_BE0_Study/tree/main/ens-library-app/src/main/java/com/group/enslibraryapp/daliy/dayfour

 


1일차 전체 후기

답변 0