블로그

승현

인프런 워밍업 클럽 스터디 1기 FE | 1주차 발자국

시작Day2 음식 메뉴를 React가 아닌 Vanila JavaScript로 도전해봤습니다. 처음 도전하는 Vanila JavaScript인 만큼 많은 자료와 시간을 들여 완성해봤는데요!The Venti의 메뉴를 json파일로 묶고 json파일을 불러와 메뉴를 보여주는 방식으로 접근했습니다. 개요파일구조index.html과 venti.json을 제외한 나머지 component들은 src폴더에 묶어서 정리했습니다.component 폴더에는 MenuButton.js와 메뉴판인 VentiMenu.js이고core폴더에는 각 컴포넌트를 불러오고 event를 실행시킬수 있는데 주체인 Component.js를 정의했습니다.이외에 index.html에 직접적으로 보여줄 app.js, main.js를 정의했습니다. Index.htmlapp.jsthis.state 를 Object인 json파일의 값을 받아야 하기에 위와 같이 초기화해주었고비동기처리로 loadJSON함수를 실행하여 state에 할당했습니다!app.js는 최상단 부모 컴포넌트이기에 자식 컴포넌트인 MenuButton.js와 VentiMenu.js를 렌더링하게 설정!Menu에는 test2인 값에 따라 값이 렌더링 될 수 있게 하였으며MenuButton은 state값이 filter될 수 있도록 설정! 이외에 나머지 파일과 다른 세부 코드들은 깃허브에 올렸습니다!!https://github.com/wink4u/inflearn_warmingup_FE_1/tree/main/project_1결과물아쉬운점초깃값 this.state의 값을 JSON에서 할당을 받고 렌더링을 해야하는데, 먼저 렌더링이 되어 빈 배열값이 출력이 되는점을 해결을 못하였다. 이것을 해결할 것 이다. CSS를 더욱 신경을 못 쓴게 아쉬웠다..

프론트엔드인프런워밍업클럽FE1기

crispin

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

0기에 백엔드 스터디에 이어 1기 프론트엔드 스터디를 신청하고, 참여하였다.신청 이유신청하게된 가장 큰 이유는 자바스크립트 랑 JQuery 를 조금씩 사용했었는데, 사실 자바스크립트 를 제대로 공부했던 적이 없고, 이직하는 곳에서는 백엔드와 프론트엔드가 명확하게 나뉘게 되어 이직하기전 프론트엔드 지식을 조금이라도 학습하면 협업을 할때 도움이 많이 될것 같아 신청하게 되었다.자바스크립트 미션아직 1단계 완료 후 2단계를 진행하고 있다. 생각외로 많이 어려워서 진행 속도가 많이 느리다. 리액트 부분으로 넘어가면 훨씬 어려워진다고 했는데 0기때 왜 프로트엔드에서 우수 러너가 적게 나왔는지 새삼 느끼고 있다. 1주차 느낀점하필 이직 시기와 겹치는 바람에(심지어 지역이동..) 거주지를 알아보고, 이직회사에서 사용하는 기술을 다시 한번 살펴보는 등 스터디외에도 할게 너무 많아 정신없이 보내고있다. 우선순위를 잘 정해서 2주차를 진행해야할것 같다.정리현재 서포터로도 참여하고 있을 정도로 애정이 정말 많이 가는 스터디다. 이런저런일로 많이 바쁘고 정신이 없지만 조금이라도 함께하는 러너분들에게 도움이 되기 위해 노력해야겠다.

프론트엔드워밍업클럽스터디프론트엔드1기회고발자국

잇택잇

[인프런 워밍업 스터디 클럽 1기] 첫번째 발자국

원본 : https://itaekit.tistory.com/12들어가기 전에인프런 워밍업 클럽 스터디 1기에 참여하게 되었다.함께 성장하는 즐거움을 맛보고 싶었고,커뮤니티로부터 동기부여도 받고 싶었고,무엇보다 막막하기만했던 독학에서 방향성을 얻고 싶었다.3주 간의 여정에서 많은 성장을 해내고 싶다.인프런 워밍업 클럽 스터디 소개인프런에서 주최하는 온라인 스터디다.이번 1기의 경우 Backend(Java/Spring), Frontend(JS/React), Product Design(Figma) 과정이 운영된다.각 과정마다 강사와 서포가 배정되고 강사님의 인프런 강의를 수강하게 된다.내가 참여하게 된 BE 스터디의 경우총 4주 진행 중 3번의 온라인 세션이 예정되어 있다.혼자서 강의를 듣고 공부했던 여태까지의 방식과 다르게,커뮤니티에 참여해 함께 공부하게 되고 강사님 가까이서 배울 수 있단 점이 참 매력적이다.또한,과제 및 미니프로젝트가 제공되어 더욱 견고한 학습을 할 수 있고,현직자의 멘토링을 받으며 학습의 방향성을 잡을 수 있단 점이 가장 큰 차별점이라고 생각한다.뿐만 아니라,수료자/우수 수료자를 뽑아 소정의 장학금, 굿즈, 인프콘 티켓, 1:1 멘토링 등이 제공되어 동기부여가 된다.(굿즈 갖고 싶다...)첫번째 Online Session : OT , 이런것 까지 알아야 할까?온라인 세션을 통해 강사님과 첫번째 만남을 가졌다.전반적인 과정 소개와 함께 과정에 앞서 알고 있으면 좋을 사전 지식들을 설명해주셨다.Java는 컴파일 언어일까, 인터프리터 언어일까?Compile고급 언어로 작성된 소스코드를 로우 레벨의 기계어로 번역하는 과정이다.한 번에 전체 코드를 모두 기계어로 번역하기 때문에 컴파일 이후 실행 속도가 빠르다는 장점이 있다.Java의 경우 .java -> .class(Bytecode)가 컴파일 과정에 해당한다.Interpreter컴파일 방식과 다르게 소스코드 한 줄 씩 읽어들여 런타임으로 번역하는 과정이다.Java의 경우 JVM이 .class를 실행할 때 처리하는 방식이다.Java는 컴파일 언어일까, 인터프리터 언어일까?Write Once, Run Anywhere- James GoslingJava는 두 방식 모두 채택하고 있다.먼저 Bytecode로 컴파일 하고 이를 플랫폼별로 최적화된 JVM이 인터프리터 방식으로 실행한다.이를 통해,기존 컴파일 언어의 단점이었던 OS 종속을 해결했고,기존 인터프리터 언어의 단점이었던 타입 불안전성을 극복할 수 있게된다.JIT (Just-In Time) Compiler인터프리터 언어의 단점은 실행 속도가 느리다는 점이다.이를 극복하기 위해 JVM은 Just-In Time Compiler라는 기술을 사용한다.JIT Compiler는 바이트코드를 분석하고,자주 실행되는 코드 블록을 미리 구분하여 Native machine code로 컴파일하여 실행 속도를 높인다.물론 장점만 얻을 수는 없다.JIT Compiler는 애플리케이션 최초 배포시 사용된 적 없는 코드로 인해 분석에 많은 리소스가 발생하게 된다.이를 해결하기 위해 배포 전 미리 웜업을 거쳐야한다.JVM, JRE, JDKJVM (Java Virtual Machine)Bytecode를 읽고 검증하여 실행하는 가상 머신이다.OS별로 최적화되어있어 동일한 Bytecode에 대해 플랫폼별 실행을 가능하게 한다.JRE (Java Runtime Envrionment)JVM 및 실제 실행에 필요한 여러 라이브러리 파일 포함하는 실행 환경JDK (Java Development Kit)JRE 및 Compiler, Debugger 등 포함하는 개발 환경Build, Build ToolsBuild소스파일로 부터 Artifact를 생성하는 일련의 과정소스코드 컴파일테스트코드 컴파일, 실행, 리포트기타 추가 설정 작업패키징Artifact 생성Build ToolsBuild 자동화 관리 프로그램으로 대표적으로 Gradle(Groovy), Maven(xml) 사용짧은 회고Java/Spring이 처음인 내게,강사님의 모든 말들은 그 자체로 지식의 확장이었다.간간히 들어서 익숙하긴한데,실제 내용을 알지 못하는 부분에 대해 많이 알아갈 수 있었다.이런 기본적인 것들을 왜 두려워하기만 했을까?알아간다는 즐거움과 함께 앞으로 알아가야 할 것들이 얼마나 많을까라는 걱정도 공존했지만,정말 오랜만에 능동적으로 학습하는 기분이 들어 행복했다.Day 01 : 서버 개발을 위한 환경 설정 및 네트워크 기초첫째날 학습한 내용은 아래와 같다.스프링 프로젝트를 시작하는 방법서버 개발에 필요한 기본 지식간단한 API 작성 및 테스트스프링 프로젝트 시작스프링 프로젝트를 시작하는 방법은 크게 2가지다.기존 프로젝트를 다운 받아 시작spring initializr를 사용해 새 프로젝트 생성1번의 경우,프로젝트를 위한 모든 의존성 및 설정이 완료되어 있어 바로 시작할 수 있다.2번의 경우,프로젝트를 위한 모든 의존성 및 설정을 직접 지정해야한다.spring initializr 사용해 프로젝트 생성하기spring initializr에 접속해 프로젝트를 설정한다.각 항목에 대한 내용은 아래와 같다.Project : 프로젝트에 사용될 Build Tools 선택Language : 프로젝트에 사용될 Main languageSpring Boot : Spring Boot의 Version을 지정괄호가 있는 version의 경우, 베타버젼이므로 안정적인 프로젝트를 위해 소괄호 없는 버전 선택을 권장Project Metadata : 프로젝트의 메타데이터를 지정Group : 그룹명, 일반적으로 도메인 작성Artifact : 애플리케이션 이름Name : 프로젝트 이름, 별도의 지정이 없는 경우 artifact명을 따름Description : 프로젝트에 대한 설명Package Name : 패키지명, Group과 Artifact의 조합으로 작성됨Packaging : 패키징 방식 지정Java : JDK VersionDependencies : 프로젝트에서 사용할 Library, Framework 등 의존성 설정Library vs FrameworkLibrary : 프로그래머가 미리 만들어져 있는 기능을 가져와 사용Framework : 프레임워크가 프로그래머의 코드를 가져가 사용Server Programming 기본 개념 : Server, Network, HTTP,  URL,  APIServer요청에 대한 응답을 처리하는 컴퓨터 또는 프로그램Network네트워크란,노드 간 연결로 형성된 디지털 전기통신망이다.각 노드는 상호연결을 통해 리소스를 공유할 수 있다.LAN 부터 Internet Network까지 그 범위는 광범위하다.Internet인터넷이란,전세계 컴퓨터 네트워를 연결하는 광범위한 네트워크를 의미한다.각 디바이스는 각각 Client/Server로 구성되며 TCP/IP 기본 프로토콜을 제공한다.WebInternet을 기반으로 HTML 문서 기반의 리소스를 공유하는 기술, 인프라 그 자체광범위한 Network의 일종인 Internet을 기반으로 HTML Resource를 공유하는 기술 및 Infra 그 자체가 Web이다. IP (Internet Protocol)Internet에서사용되는 통신 규약IP AddressInternet에 연결된 Device를 식별하기 위해 부여되는 고유 주소Domain NameDNS(Domain Name System)에 의해 IP Address와 매핑되어 사용되는 이름으로,사람이 직접 IP 주소를 다루는 것은 불편하여 고안된 방법ping www.google.com으로 구글 ip 확인ex. google에 접속하기 위해 142.250.66.100으로 접속하는 대신 google.com으로 접속PortIP를 통해 인터넷에서 하나의 디바이스를 특정할 수 있었다면,Port를 통해 해당 디바이스의 특정 프로세스에 접근할 수 있게 된다.즉, Port는 일종의 네트워크상 프로세스의 고유 주소가 되는 셈이다.HTTP (HyperText Transfer Protocol)Web에서 사용하는 기본 통신 규약HTTP Method서버가 수행해야 할 action을 지정하는 방식으수행 목적에 따라 GET, POST, PUT, DELETE 등으로 구분된다.HTTP RequestHTTP Request FormatClient에서 Server로 보내는 HTTP 포맷첫째줄에 HTTP Method와 함께 Path 정보가 포함됨HTTP ResponseHTTP Response FormatServer에서 Client로 보내는 HTTP 포맷첫째줄에서 Status Code를 반환URL (Uniform Resource Locator)URL SampleWeb 상에 존재하는 Resource의 주소API (Application Programming Interface)프로그램간 통신하기 위한 규약정해진 약속에 따라 특정 기능을 수행@SpringBootApplication스프링 프로젝트를 실행시키기 위해 필요한 설정들을 모두 자동으로 처리GET API 개발 및 테스트@RestControllerController Class 등록을 위한 어노테이션@GetMapping(Path)GET Method에 대한 API 지정을 위한 어노테이션@RequestParamQuery 추출을 위한 어노테이션GET API 실습API : GET /addQuery로부터 두 정수를 추출하여 더한 값 반환과제 리뷰첫째날 과제는 어노테이션에 대한 학습이었다.소스코드에서 메타데이터를 제공할 수 있는 방법인 어노테이션은프레임워크에서 적극적으로 활용되기 때문에 어노테이션에 대한 기본적인 학습이 필요했다.이전까지 써본 어노테이션이라고는 @Override, @FunctionalInterface 정도였지만이번 과제를 통해 어노테이션에 대한 기본적인 내용을 정리할 수 있었다.Annotation 기본 지식소스코드에 메타데이터를 직접 추가하기 위해 고안된 방법으로JDK 5부터 지원한다.주석과 같이 로직 자체에 영향을 주진 않지만 코드의 연결 방법, 구조를 변경하므로실행 흐름을 변경할 수 있다.컴파일 전처리 대상인 주석과 다르게,런타임 시점에 사용될 정보를 포함할 수 있다.클래스, 메서드, 변수 등에 추가할 수 있다.어노테이션의 종류로는,기본 제공되는 Built-In 어노테이션,직접 만드는 사용자 정의 어노테이션,그리고 사용자 정의 어노테이션을 만들 때 필요한 메타 어노테이션 등이 있다.어노테이션은 오직 자신이 유효한 프레임워크에서만 동작한다는 특징을 가진다.ex. @SpringBootApplication은 Spring framework에서 동작하며 실행에 필요한 설정들을 처리한다.짧은 회고다음 스텝으로 넘아가는 것에 두려움을 가졌던 내 학습 스타일이 깨져가고 변해가는 귀한 시간이었다.본격적인 스프링 프레임워크 학습에 앞서 필요한 지식들을 학습할 수 있었다.그동안 대충 알고 있었던 용어들에 대해 정리하니 개운해졌다고나 할까.특히 그동안 괜히 어려울 것만 같았던 스프링 프로젝트를 직접 실습해보며"생각보다 할만한데?"라는 느낌을 받았다.왜 겁을 먹었던 걸까,이렇게 즐겁기만 한데!자,시작이 반이라고 했던가.정말 필요한 기본 지식들은 모두 끝났다.본격적인 스프링 프레임워크의 학습에 뛰어들어보자!Day 02 : 첫 HTTP API 개발두번째 날,POST API 실습을 진행했다.POST API 개발 및 테스트조회를 위해 사용했던 GET API와 다르게,POST API는 Server에 데이터 생성을 요청한다.생성을 위해 필요한 데이터는 기본적으로 Request Body의 형태로 전달한다.@PostMapping(Path)POST API 지정을 위한 어노테이션@RequestBodyRequest Body를 DTO로 받기 위해 사용하는 어노테이션DTO의 field와 이름이 같은 경우,자동으로 매핑되어 처리POST API 실습POST /multiply전달된 Request Body의 두 Integer 객체로부터 곱을 구하여 전달유저 생성 API 개발 및 테스트이어지는 API 실습에서는,User DTO를 활용하여User를 생성하는 POST API를 만들고전체 User를 조회하는 GET API를 만든다Controller에서 사용하기 위해 동일한 객체에 대해 다양한 DTO를 설계하였다.Request Body로 받아들이기 위한 DTO실제 서버에서 사용할 UserResponse로 사용할 DTO이를 통해 각 객체의 역할을 구분할 수 있었고,용도에 맞춰 사용해 개발하기 한결 수월했다.과제 리뷰둘째날 과제는 주어지는 API Specification에 따른 API 개발이었다.그 중,Query에 날짜를 전달하여 요일을 전달받는 GET API 문제가 가장 재밌었다.특정 날짜에 대해 요일을 영어로 출력하되,이 때 마지막의 "DAY"는 제외하고 반환해야한다.Response DTO를 설계하여문제에서 주어진 JSON 포맷으로 반환하는 것 또한 공부가 되었다.짠-짧은 회고API 실습을 통해Client와 Server가 통신하는 원리를 배울 수 있었다.뿐만 아니라,API 명세에 따라 구현을 하다보니정말 서버 개발자로써 일을 하고 있는 것 같은 기분이 들어 즐거웠다.과제 중 list 형태의 Request Body로부터 합을 계산하여 반환하는 문제가 있었는데,해당 문제에는 Stream API를 사용하니뭐랄까... "은근 Java 좀 치는데?"같은 감상도 들었다.배웠던 내용이 자연스레 떠오르고 코드로 작성되는 순간의 희열은 이루 말할 수 없는 것 같다.아,아직 API 요청에 대해 DB를 연동하지 않았기 때문에Server 메모리 상에서만 데이터를 다루고 있다.얼른 DB를 배워 연동해서 실제 살아있는 서버를 만들고 싶다.Day 03 : 기본적인 DB 사용법DB 활용에 앞서 DB에 대한 기초 및 연결을 학습하는 시간이었다.Database저장 원리기본적으로 컴퓨터의 모든 리소스는 Disk와 같은 저장장치에 반영구적으로 보존된다.프로그램을 실행하게 되면 디스크로부터 프로그램을 RAM에 올려 CPU로 계산을 한다.그렇다면, 클라이언트로부터 데이터를 받은 서버 컴퓨터에서는 해당 데이터를 보존하기 위해 어떻게 해야할까?당연히 서버 컴퓨터에 저장해야한다.RAM과 같이 휘발성이 없는 장치에다가.물론, 서버 컴퓨터에 파일 형태로도 보존할 수 있다.그렇지만 대용량 데이터에 대해 효율적인 연산을 지원하는 DB의 사용이 일반적이고 정석이다.따라서 서버 개발자라면,DB에 대한 지식이 필요하다.DatabaseDB는 대용량 데이터에 대해 효율적인 연산을 제공하는 가상의 저장장치 및 프로그램이다.구조화 방식에 따라 RDB, NoSQL 등이 있으며각각의 목적에 따라 사용된다.프로그래머는 DBMS(Database Management System)을 통해 DB를 관리하는데,여기에는 MySQL, PostgreSQL, MongoDB 등 다양한 제품이 있다.이 때,DBMS에서 DB와 통신하기 위해 사용되는 언어를 SQL(Structured Query Language)라고 한다.Spring에서 DB 연동하기application.ymlSpring framework가 DB에 접근하기 위한 설정 등록한다./resource에서 관리하며 이미 application.properties가 있는 경우 확장자를 변경한다.dependencyapplication.yml에서 mysql을 위한 Driver를 지정하였는데,이를 위해 의존성에 추가한다.IntelliJ에서 DB연동IntelliJ Ultimate를 사용하는 경우,IDEA와 DB를 연결하여 DBMS로 활용할 수 있다.해당 서비스 이용이 어려운 경우,MySQL Client 또는 DBeaver와 같은 프로그램을 사용하면된다.intelliJ에서 MySQL 연결JdbcTemplate를 사용한 간단한 DB 연동 프로그래밍DB를 연결했으니 직접 사용해본다.JdbcTemplate 필드에 대한 의존성 주입서버 코드에서 DB와 연동하기 위한 API로 JdbcTemplate를 사용한다.API 코드 수정이 때 주의해야 할 점으로,jdbcTemplate 필드로 SELECT문을 사용해 반환받은 결과는 List다.또한,RowMapper 구현을 통해List를 생성하기 전 Table의 각 row에 대해 필요한 정보를 지정하여 임의의 객체를 만들어야 한다.과제 리뷰이번 과제는 람다식에 대한 내용이다.함수형 인터페이스에 대해 익명 클래스를 기반으로 동작하는 람다식은 JDK 8부터 추가되었다.생산성 및 가독성을 올려주며,함수형 프로그래밍을 구현할 수 있게 된다.이미 Java 문법에서도 배웠던 내용이라다시 한번 점검할 수 있었다.짧은 회고살아있는 서버를 만드는 일은 정말 즐거웠다.점점 실제 서비스를 만들 수 있는 재료들을 배워가고 있다는 생각에,빨리 이 과정을 졸업하고 프로젝트에 뛰어들고 싶어 근질근질하다.이전에 SQLD를 준비하며 배웠던 SQL이 기억나조금 더 수월하게 따라갈 수 있었다.역시 배운 건 어디 안간다.간단한 CRUD 정도야 바로 사용할 수 있었지만,복잡한 쿼리문을 설계하고 이를 스프링에서도 사용하기 위해DB, SQL을 깊게 파봐야할 것 같다.Day 04 : DB를 사용해 만드는 API지난 시간과 이어지는 DB연동으로,UPDATE, DELETE API를 작성했다.PUT API로 UPDATE 기능 구현, DELETE  API로 DELETE 기능 구현각 API에 대해 예외처리한 코드다.과제 리뷰계속해서 이어지는 API 실습이다.서버 개발자는 결국 Client 요청을 처리하기 위한 API를 개발하는 일을 하는만큼,API 연습만이 살 길이다!과제 중,로직도 복잡하고 DB 테이블을 확장해야 했던 3번이 가장 재미있었지만...이유를 몰라 헤맸던 문제 2번을 해결한 경험을 나누고자 한다.RequestBody DTO에 기본 생성자가 정의되지 않은 경우처음 작성한 코드에는 기본 생성자를 작성하지 않았다.단순히 @RequestBody에 의해 오버라이드한 생성자가 호출되는 줄 알고 아무런 문제를 느끼지 못했다.이상없다고 단정지은 코드...그러나 INSERT 되지 않았다.Status code는 400을 반환 받았고 요청 자체가 잘못되었음을 알 수 있었다.무엇이 문제일까?이를 이해하기 위해서는 @RequestBody의 동작을 이해해야한다.@RequestBody의 동작@RequestBody는 요청으로 넘어온 객체를 지정한 DTO에 매핑시켜 반환한다.이 때,Spring은 Reflection을 사용하는데DTO 클래스에 기본 생성자가 없는 경우 변환하는 과정에서 문제를 일으킬 수 있다.따라서,DTO 클래스를 생성할 때는 반드시 기본 생성자를 작성한다.편-안짧은 회고많은 API 연습을 통해Client와 Server 사이에서 이루어지는 동작에 대해 보다 이해할 수 있었고,무엇보다 API 작성에 자신감을 갖게 되었다.가장 기본이자, 가장 중요한 CRUD API에 대해 모두 학습하였다.API 디자인은 더 많은 연습이 필요하겠지만,API 명세를 이해하고 이를 바탕으로 실제 구현하는 일은 곧 내가 현업에서 밥 먹듯이 하게 될 일이다.기본기가 중요한만큼,더욱 집중해서 학습하고 연마하자!Day 05 : 클린코드의 개념과 첫 리팩토링1주차 마지막 날이다.단순 구현에서 벗어나 좋은 코드에 대한 고민을 시작하게됐다.Clean Code개발자를 준비하면서 심심찮게 들어본 단어 중 하나가 바로 '클린코드'다.실제 개발자는 코드를 작성하는 시간보다 읽는 시간이 더 많다고 한다.어느 한 사람만 이해하고 시간이 지나면 아무도 이해하지 못하는 코드는 결코 좋은 코드라고 말할 수 없을 것이다.코드란 요구사항에 대한 실제 구현이며,좋은 코드란 읽기 좋은 코드를 의미한다.즉,클린코드로 작성하여 가독성을 높여 최종적으로는 생산성을 높이는 것이 가장 중요한 목적이다.Layered Architecture이전의 코드는 모두 하나의 Controller에서 작성되었다.즉, Controller에서 작성된 하나의 메서드가API 진입점으로 사용되고로직을 수행하며DB와 통신을 한다더 좋은 코드를 위해,더 좋은 구조를 위해,역할에 따라 클래스를 구분하고이를 기반으로 통신하는 Layered Architecure를 적용한다.ControllerAPI의 진입점으로 사용되는 클래스다.API 진입점으로 Service와 통신Service비즈니스 로직을 작성하는 클래스다.Controller, Repository와 통신RepositoryDB와 통신하는 클래스다.Service, Database와 통신과제 리뷰좋은 코드를 위한 고민은 멈추지 말아야한다.작성하는 입장보다 읽는 입장을 고려하며 작성하는 것이 좋은 자세일 것이다.그리고 이러한 고민은 아주 오래 전 부터 수많은 개발자에 의해 이뤄져왔다.어느정도 일반적인 클린코드에 대한 가이드가 생겨났다.<Clean Code>라는 책이 좋은 참고가 될 것이며,이론적으로 아는 것 보다 실제 작성하고 읽어보며 체득하는 것이 더욱 유익할 것 같다.짧은 회고처음으로 내가 작성한 코드를 바라보게 되었다."내가 작성한 코드는 좋은 코드인가?"라는 고민을 멈추지 말아야겠다.좋은 습관이 벨 수 있도록,고민하고 작성하자!두번째 Online Session : Live Q&A두번째 온라인 미팅이 진행되었다.이번 세션은 QnA 위주로 진행되었고 가장 도움되었던 내용을 기록해본다.Q. 포트폴리오 주제지원하는 회사에서 하고 있는 프로덕트가 최고다.가장 가고 싶은 회사 한 곳을 선정하여 관련 서비스를 만들어보자.실제 서비스되고 있는 기능을 분석하고 구현하면서 자신의 사용 경험을 기반으로 새로운 기능도 추가해보자.분명 좋은 평가를 받을 것이다.Q. 신입 개발자 역량회사의 사정과 규모에 따라 나뉘겠지만 멘토님이 제시해주신 방향은 아래와 같다.개발자 시작 가능한 수준기본적인 Java 이해 : Java 기본서 90% 이해 및 기본적인 구현 능력기본적인 CRUD 및 Spring 기본최소한의 배포취업 99%의 능력Java 심화추천 도서 : <이펙티브 자바>, <모던 자바 인 액션>, <자바 성능 최적화>Spring 심화 : 통계, 엑셀, 메일을 Spring으로 구현할 수 있어야 함기술에 대한 고민을 할 수 있을 정도의 이해무중단 배포, 서버 확장 전략이번 스터디를 통해 내 수준이 어디까지 올라갈지는 모르겠으나,폭.풍.성.장 하자!1주차 후기이렇게까지 많이 배운 한 주가 있었나 싶을 정도로많이 배웠고, 연습했고, 성장했다.한편으로,이전부터 이렇게 학습했다면 진작 취업하지 않았을까? 라는 아쉬움이 사무쳤다.배운 내용을 완벽히 이해해야만 다음 단계로 넘어갈 수 있었고무엇을 학습하면 좋을지 몰라 닥치는대로 학습했고정작 중요한 서버 지식과 스프링을 배우기 위해서 무엇을 하면 좋을지 몰라지레 겁을 먹었던 지난 날들이었다.이제라도,어떻게 성장해야하는 지 알아가고 있음에 감사하자.제대로 성장하는 방법을 알아가고 있음에 위로를 얻자.앞으로의 성장이 기대되기 시작한 1주차였다.

백엔드워밍업클럽스터디백엔드Java/Spring최태현멘토님

sun

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

[강의 내용 정리]Section 1. API 만들기@RestController : 아래 클래스를 api의 진입 지점으로 설정GET(@GetMapping(”/path”))@RequestParam : 쿼리를 통해 넘어온 데이터를 파라미터로 줄 때 사용파라미터를 객체로 받을 수 있음(DTO) → 객체로 받으면 @RequestParam 안 씀DTO에 생성자, getter 생성Controller에서 getter가 있는 객체를 반환하면 json이 됨POST(@PostMapping(”/path”))Body로 데이터를 받을 때, JSON 사용@RequestBody : http body의 json을 파싱해서 객체(dto)로 만들 때 사용DTO에 getter 생성Section 2. Database 조작하기CRUD API를 만든다 == 어떤 대상에 대해 생성, 조회, 업데이트, 제거 API를 만든다JDBC와 연결private final JdbcTemplate jdbcTemplate; public UserController(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } jdbcTemplate.query(sql, RowMapper 구현 익명클래스)⇒ Lamda로 더 간결하게 변경 가능jdbcTemplate.update()⇒ 여기서 update : sql의 UPDATE와 달리, 내용이 수정될 때 사용(INSERT, UPDATE, DELETE)Section 3. 역할의 분리와 스프링 컨테이너Controller 3단 분리(Layered Architecture)Controller : API의 진입 지점. 즉, HTTP 관련 부분 처리(”path”) (HTTP Body를 객체로 변환)Service : 예외 처리 (유저가 있는지 없는지 확인)Repository : DB와의 통신 (SQL)[과제 정리][과제 1] 어노테이션[과제 2] GET, POST API[과제 3] 람다식[회고]스터디 참가 전, 강의를 모두 수강하긴 했지만 내 지식으로 만들지 못한 부분이 많았다. 강의를 다시 수강하며 부족한 부분을 채우고자 스터디에 참여하게 되었다.일정표에 따라 강의를 재수강하고 과제를 수행하면서 내가 부족한 부분이 어느 부분인지 확실하게 알 수 있었다. 특히, 자바에 대한 학습이 더 많이 필요함을 느꼈다.2주차에는 강의 수강과 과제 수행을 좀 더 성실히 수행하고자 한다!

백엔드워밍업클럽

전다윤

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

Section 1 - 생애 최초 API 만들기 Java를 공부하기 전에 알아두면 좋을 것들JAVA의 경우 C언어와는 다르게 운영체제에 따라 각각의 컴파일러가 필요하지 않다. JAVA 컴파일러의 결과물이 각각의 운영체제의 JVM 위로 올라가게 된다.JVM : 바이너리 코드를 읽고 검증하고 실행JRE : JVM + 실행에 필요한 라이브러리 파일JDK : JRE + 개발을 위한 도구(컴파일러, 디버그 도구) JDK > JRE > JVM빌드(build) : 소스코드 파일을 컴퓨터에서 실행할 수 있는 독립적 SW(Artifact)로 변환하는 과정실행(run) : 작성한 코드를 컴파일을 거쳐 작동하는 것 (Artifact가 있을 수도 있고 없을 수도 있다)Java 빌드 도구 : 빌드 과정 자동화와 외부 라이브러리 관리를 위해 빌드 툴을 사용 예) ANT, Maven, Gradle  스프링 프로젝트 시작이미 만들어진 스프링 프로젝트를 다운로드spring initializer를 이용해 새로운 프로젝트 시작 https://start.spring.io/ 어노테이션@SpringBootApplication 어노테이션의 경우 스프링을 실행시킬 때 필요한 다양한 설정들을 자동으로 해준다.여기서 과제로 어노테이션에 대한 리서치 과제를 진행하였다.[과제 #1] 어노테이션 네트워크서버 : 어떠한 기능을 제공하는 프로그램을 실행시키고 있는 컴퓨터서버라는 컴퓨터에게 요청을 하기 위해서는 인터넷, 네트워크를 사용한다.  HTTP와 API(웹을 통한)컴퓨터 간 통신은 HTTP라는 표준화된 규약을 통해 이루어진다.HTTP 요청은 HTTP Method(GET, POST)와 Path(/portion)가 핵심이다.요청에서 데이터를 전달하기 위한 방식에는 쿼리와 바디 방식이 있다.HTTP 응답의은 상태코드 가 핵심이다.클라이언트와 서버는 HTTP를 주고받으며 기능하는데 이때 정해진 규칙이 API이다. API 개발하기API Specification(명세) : API를 개발하기 전에 API의 HTTP method, HTTP path, 쿼리와 바디, API의 반환 결과를 결정해야 한다.GET API@RestController : 주어진 Class를 Controller로 등록한다.Controller : API의 입구DTO(Data Transfer Object) 객체 : '쿼리'를 서버 안 Controller로 전달하는 역할POST API쿼리를 사용하지 않고 바디(Body)를 사용한다.Json : 바디에 데이터를 담아주는 방식   Section 2 - 생애 최초 Database 조작하기Database지난 시간에 서버를 종료했다가 시작하면 유저 정보가 전부 사라지는 것을 확인할 수 있었다. API의 결과가 RAM(메모리)에 저장되기 때문에 서버는 Disk(장기기록장치)에 정보를 저장해야 한다. 이럴 때 Database를 사용할 수 있다.Database : 데이터를 구조화 시켜 저장Relational Database : 데이터를 표처럼 구조화 시켜 저장MySQL은 대표적인 RDB이다.데이터베이스를 조작하기 위해서 SQL을 사용해야 한다. MySQL접근 방법Intellij Ultimate에서 MySQL에 바로 접근이 가능하다.CLI로 접근하기 SQLDDL(Data Definition Language) : 데이터를 정의하는 SQLDBcreate database [데이터베이스 이름]; show databases; drop database [데이터베이스 이름]; use [데이터베이스 이름];테이블create table [테이블 이름] ( [필드1 이름] [타입] [부가조건], [필드 2 이름] [타입] [부가조건], ... primary key ([필드 이름]) ); show tables; drop table [테이블 이름];DML(Data Manipulation Language) : 데이터를 조작하기 위한 SQLCRUDCreate(생성) : 데이터 삽입Retrieve or Read(읽기) : 조회Update(업데이트) : 수정Delete(제거) : 삭제# 데이터 넣기 INSERT INTO [테이블 이름] (필드1이름, 필드2이름, ...) VALUES (값1, 값2, ...) # 데이터 조회하기 SELECT * FROM [테이블 이름] WHERE [조건]; # 데이터 업데이트하기 UPDATE [테이블 이름] SET 필드1이름=값1, 필드2이름=값2, ... WHERE [조건]; # 데이터 삭제하기 DELETE FROM [테이블 이름] WHERE [조건]; Spring에서 Database 사용resources 폴더에 application.yml 파일을 생성해 스프링 서버와 연결할 DB 정보를 설정한다. POST API 변경jdbcTemplate을 이용해 SQL을 날릴 수 있다."INSERT INTO user(name, age) VALUES(?, ?)"; 와 같이 값이 들어가야 하는 부분에는 ?를 사용한다.jdbcTemplate.update(sql, request.getName(), request.getAge());jdbcTemplate.update는 INSERT, UPDATE, DELETE 쿼리에 사용 가능하다.첫 파라미터는 sql을 받고, ?를 대신할 값을 차례로 넣어준다.GET API 변경jdbcTemplate.query(sql, RowMapper 구현 익명클래스) : query를 사용하면 SELECT 쿼리를 날릴 수 있다.@Override 함수 : ResultSet 객체에는 결과가 담겨있고, 이 객체에 getType("필드이름") 을 사용해서 실제 값을 가져온다.JAVA 람다를 이용해 더 간결한 코드를 간결하게 변경할 수 있다. [과제 #3] 람다식과 익명 클래스예외 처리사용자가 없으면 IllegalArgumentException과 같은 표준 예외를 throw한다. 사용자의 존재 여부를 확인하고 없으면 예외를 던져 200 OK 대신 500 Internal Server Error가 나오게 한다.여유롭게 강의를 수강하고 과제를 수행할 수 있을 것이라고 생각했는데, 강의도 진도표보다 적게 들었고 두 번째 과제도 수행하지 못했다.😭 다음 주에는 시간이 있을 때 미리 강의도 듣고 과제도 수행해야겠다는 생각이 들었다.

백엔드인프런워밍업클럽1기BE

dwsrh03

[인프런 워밍업 클럽 1기] BE 1주차 발자국

인프런 메일을 통해 이 스터디에 알게 되었다. 부트캠프를 수강한지도 오래되었고, 프로젝트에 참여한 지도 오래되어 서버 개발에 대해 기억이 가물가물해져서, 사실상 다 까먹어서 참여하게 되었다. 그리고 혼자 공부하다보면 스스로와 타협하게 될 때가 많다. 이러다 보면 기간은 길어지기만 하는데 다행히 나에게 필요한 내용의 스터디가 있어서 참여하였다. 학습 요약 및 회고이번주는 Section1과 Section2를 수강했다. 이 과정을 수강하며 API를 만들고, Database를 조작하는 방법에 대해 알 수 있었다.Day 1스프링에 대한 기본적인 내용과 서버 개발을 하는데 필요한 다양한 기초 지식들을 배울 수 있었다. 간단한 GET동작을 하는 API도 생성하였다.자세한 내용은 다음의 링크에 정리했다.https://blog.naver.com/le_voyage_03/223431252952Day 2GET동작에 이어 POST API를 생성했다.GET과 POST를 응용하여 다양한 API를 생성했다.저장한 사용자들의 데이터들이 서버를 종료하면 초기화되는 문제를 발견하였다.자세한 내용은 다음의 링크에 정리했다.https://blog.naver.com/le_voyage_03/223432427713Day 3Day 2에서 발견한 문제점을 해결하기 위해 Database를 사용하였다.디스크와 메모리의 차이Database를 사용하기 위해 MySQL을 저장하고 실행시키며 동작하는 명령어에 대해 배웠다.CRUD(Creat, Read, Update, Delete)로 데이터를 조작하는 방법에 대해 배웠다.생성한 Database를 Spring과 연결하였다.Day 4스프링으로 Database에 접근하여 CRUD를 했다.발생할 수 있는 예외 상황을 처리하였다.한 클래스인 Controller가 너무 많은 역할을 하는 문제를 발견하였다.  과제 및 회고Day 1https://github.com/zzzyoonnn/libraryApp/blob/main/task/Task01.md어노테이션에 대해 다시 한번 개념을 정리할 수 있었다.Day 2https://github.com/zzzyoonnn/libraryApp/blob/main/task/Task02.md강의를 보며 코드를 따라 치다가 혼자서 하려니 막상 내가 제대로 이해하지 못했음을 깨달았다. 강의를 정리해둔 내용을 다시 보며 이해할 수 있었다. 다행이다.Day 3https://github.com/zzzyoonnn/libraryApp/blob/main/task/Task03.md람다와 관련된 내용들을 정리할 수 있었다. 마무리계획표에 따라 강의를 수강하겠다 다짐했건만 자꾸 쳐지는 건 어쩔 수 없나보다. 그래도 다행히 너무 뒤쳐지지 않게 강의를 수강할 수 있었다. 기운 내자! 그리고 부트캠프를 수강한 지 오래되어 개발하는 것에 대한 두려움이 컸었는데 다행히 이전에 비해 두려움은 많이 사그라들었다. 그래도 아직은 갈 길이 멀다. 무사히 완강하고 개인 포트폴리오도 완성할 수 있길 바란다. 화이팅하자!

김형중

인프런 워밍업 스터디 클럽 1기 발자국 1회

저는 일주일동안 16강까지 강의를 수강했구요. 기본적인 CRUD api 사용법과 데이터베이스 사용법에 대해 알수 있어서 좋았습니다. 맨처음에 강의를 수강을 시작하면서 개발환경 세팅에 관해서 조금 고민이 생겼었는데요.개인적으로 vscode를 크게 불만없이 사용중이라 제 개발환경에 크게 벗어나고 싶지 않는 점이 가장 컸습니다.그래서 저는 vscode extention을 통해 자바 에디터환경을 준비했고,강사님과는 살짝 다른 openJDK인 Amazon Corretto 11를 다운받아 설치했습니다.https://docs.aws.amazon.com/corretto/latest/corretto-11-ug/downloads-list.html그래서 지금까지 사용해본바, 아직까지는 크게 불편한 점이 없어서 다행입니다. 강의를 수강하면서 이제 첫번째 프로젝트를 만들어야 했는데요. 문제는 현재 자바스프링 버전에서는 제가 원하는 자바와 스프링 버전을 선택할수 없었습니다.제가 프론트엔드 강의를 들을때 라이브러리의 버전이 안맞아서 코드 작성에 고생했던 기억이 떠올라서 이건 꼭 맞춰서 가야겠다는 생각이 강력히 들어서 방법을 찾기 시작했습니다.제가 할수 있는 모든 방법을 통해서 방법을 알아보니 생각보다 변경이 간단한 부분이었고, gradle환경의 변수내용만 바꿔주면 강의와 동일하게 프로젝트를 설정해서 진행할수 있었습니다.그리고 강의를 들으면서 어노테이션을 계속 사용하게 되는데, 원하는 어노테이션이 자동으로 import되지 않더라구요.그래서 확인해보니, 다음과 같은 디펜던시를 설정해줘야지 웹api관련 어노테이션을 사용할수 있는걸 알았습니다.implementation 'org.springframework.boot:spring-boot-starter-web'이제 자동 import는 문제없이 잘 되게 되었습니다! 저는 mac환경에서 프로젝트를 진행하고 있는데요. 매번 gradle파일을 수정할때마다, 코드를 변경할때마다 매번 build를 진행해야되고, 서버를 재시작해야되는 불편함이 있었습니다.그래서 분명히 코드가 변경될때마다 자동으로 빌드해주고 서버를 재시작해주는 설정이 있을거라고 확신을 갖고 검색을 했습니다.검색을 통해 스프링 데브 툴이라는 개발 디펜던시의 존재에 대해서 알게되었고,developmentOnly 'org.springframework.boot:spring-boot-devtools'application.properties를 작성했지만 원하는대로 작동되지 않았습니다..spring.devtools.restart.enabled=true spring.devtools.restart.poll-interval=2000 spring.devtools.restart.quiet-period=1000그래서 검색결과는 아주 오래전부터 지원되고 있음을 알게 되었는데, 정작 작동되지 않으니, 너무 답답한 상황이었습니다. https://github.com/redhat-developer/vscode-java/issues/3392 그런 와중에 우연히 스택오버플로우 글을 보게되었는데, 두개를 동시에 실행해야 된다는 정보를 보게 되어서 그대로 했더니 동작하게 되었습니다! https://stackoverflow.com/questions/54937518/visual-studio-code-spring-boot-reload-static-content./gradlew bootJar --continuous ./gradlew bootRun 그외에 자바 스프링을 공부하면서 알게된점은 결과 반환을 json 형식으로 보내주려면 객체를 새로생성해서 데이터를 넣어주면 간단하게 할수 있게되었구요.DTO의 역활이 클라이언트 -> 서버 로 데이터를 제자리에 알맞게 변환시키는것도 중요하지만 반대로 서버 -> 클라이언트로 데이터를 전달할때도 중요하게 사용되어진다는걸 알게되었습니다.자바에서도 람다와 익명클래스로 코드를 좀더 간결하게 작성할수있는 방법과 데이터베이스 조작언어에 관해서 좀더 다양한 키워드를 알수 있어서 좋았습니다. 특히 미션 4번에서는 데이터베이스의 있는 내용을 특정 기준으로 분류해서 모든 값을 더한 결과값이 최종 데이터가 되어야 되는 미션이었는데요.맨처음에는 여기서 단순 쿼리로 데이터를 받아와서 컨트롤러에서 처리하는것을 생각해보았지만, 강사님께서 sum, gruop by 옵션에 대한 힌트를 주셔서 이것을 활용하면 더 훨씬 간결한 코드가 나올것같아 관련 내용을 검색해서 찾아보았습니다. sum과 group by를 사용한다면select sum(price) as seles_amout from fruit group by is_sold having is_sold = 1;이런식으로 작성해서 쿼리를 두번 호출하면 원하는 데이터를 가져올수 있게 됩니다. 그런데 저는 이 코드에서 두개의 컬럼의 결과값을 한번에 가져올수 있을거라는 생각이 들어서 조금더 검색해보기로 했습니다. sql에서도 다양한 조건 검색을 제공하고 있는데 그중에서 case를 사용해서 원하는 컬럼의 값만 가져올수 있는걸 알게 되었습니다.제가 최종적으로 작성한 코드는 다음과 같고.SELECT SUM(CASE WHEN is_sold = 1 THEN price ELSE 0 END) AS seles_amount, SUM(CASE WHEN is_sold = 0 OR is_sold IS NULL THEN price ELSE 0 END) AS not_sales_amount FROM fruit이고 결과적으로 gruop by는 사용하지 않았지만, 깔끔하고 한번에 가져올수 있어서 만족합니다. 다음 주차의 목표는 ci/cd 설정및 아마존 배포까지 해보는것입니다!목표를 이룰수 있도록 열심히 한번 해보겠습니다.

백엔드

배고픈 코뿔소

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

강의(웹을 통한) 컴퓨터 간의 통신은 HTTP라는 표준화된 방식이 있다.HTTP 요청은 HTTP Method(GET, POST)와 Path(/portion)가 핵심이다.요청에서 데이터를 전달하기 위한 2가지 방법은 쿼리와 바디이다.HTTP 응답은 상태 코드가 핵심이다.클라이언트와 서버는 HTTP를 주고받으며 기능을 동작하는데 이때 정해진 규칙을 API라고 한다. @RestController : 주어진 Class를 Controller로 등록Controller : API의 입구@GetMapping("/add") : 아래 함수를 HTTP Method가 GET이고, HTTP path가 /add인 API로 지정@RequestParam : 주어진 쿼리를 함수 파라미터에 넣음GET /add?number1=10&number2=20 : 같은 이름을 가진 쿼리의 값이 들어옴JSON- 객체 표기법, 즉 무언가를 표현하기 위한 형식ID - 유저별로 겹치지 않는 유일한 번호스프링 프로젝트를 시작하는 방법과 실행하는 방법네트워크, IP, 도메인, 포트, HTTP 요청과 응답 구조, 클라이언트-서버 구조, API와 같은 기반 지식Spring Boot를 이용해 GET API와 POST API를 만드는 방법 디스크와 메모리의 차이를 이해하고, Database의 필요성을 이해함MySQL Database를 SQL과 함께 조작할 수 있음스프링 서버를 이용해 Database에 접근하고 데이터를 저장, 조회, 업데이트, 삭제할 수 있음API의 예외 상황을 알아보고 예외를 처리할 수 있음 배운 내용을 다시 배우지만 항상 새로운 느낌이 든다. 부족하다는 생각을 많이 느꼈고 더 열심히 공부해야겠다는 생각이 들었다. 2주차부터는 좀 더 집중해서 듣고 빠르게 습득하도록 노력해야겠다.미션어노테이션과 람다식 이론은 책을 통해 찾아보고 만약 책의 내용이 부족하면 인터넷을 통해 찾아본다.GET API와 POST API 과제는 강의에서 배운대로 개발해보고 안 되는 경우만 인터넷을 통해 찾아본다. 인터넷으로 해결이 안 되는 경우는 다른 분들이 한 과제를 보고 다시 한 번 개발해본다. API 강의를 보고 난 뒤에도 생각보다 과제를 헤맸다. 아직 부족하다는 것을 많이 느끼게 되었고 공부를 더 열심히 해야겠다는 생각이 들었다.

홍승찬

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

참가계기국비학원에서 기초를 다졌지만 이제까지 MyBatis만을 사용한 프로젝트를 진행했었다. 때문에 요즘 기업에서 많이 요구하는 JPA를 공부해야겠다는 생각으로 강의를 결제했지만, 혼자서 게시판을 만들어보는 개인프로젝트를 진행하면서 차일피일 미뤘었다.그런데 마침 인프런 워밍업 클럽 스터디가 시작한다는 것을 알게 되었고, 개인 프로젝트도 어느 정도 기능 구현이 완료된 상태였기에 JPA 기초를 공부하면서 기존 프로젝트를 JPA로 마이그레이션 하는 것이 좋은 경험이 될 것 같아서 워밍업 클럽 스터디에 참여하게 됐다.배운 것1주차는 IDE설치부터 기초적인 개념을 다시 공부하는 시간을 가졌다.1 .인텔리제이와 MySql이제까지 이클립스와 오라클을 사용했지만 강의에서는 인텔리제이와 mySql을 사용해서 두 개를 써보고 있다. 그런데 확실히 인텔리제이가 이클립스 보다 더 안정적으로 느껴져서 앞으로는 인텔리제이를 쭉 사용할거 같다.(사실 SSD 교체해서 이클립스 설치는 귀찮았다.)DB는 오라클 GUI를 사용했었는데, MySql CLI를 사용하려니 살짝 어려운 감이 있었다. 다만 아직 테이블을 설정하고 만들 일이 많이 없기 때문에 크게 힘들지는 않았다. 나중에 개인프로젝트 할 때는 MySql워크벤치? 사용해서 만들 것 같다.2. API알고 있는 내용들을 복습하고 잊고 있었던 부분들을 상기시킬 수 있는 좋은 기회였다.3. 리팩토링국비교육에서는 Controller, Service, Repository를 나눠야 하는 이유를 알려주지 않고 3개가 각자 어떤 책임과 역할이 있는지 알려주지 않았었다. 그래서 국비에서 만든 프로젝트를 보면 컨트롤러에서 많은 역할을 수행하고 서비스단에서는 리포지토리로 넘겨주는 역할 밖에 없었다. 다행히 친구의 피드백으로 인해 왜 3개가 나뉘어야하고, 각자의 책임이 뭔지 알게 됐었는데, 강의에서 그런 부분을 하나하나 짚고 넘어가면서 혼자 공부했던 내용들을 다시 짚고 넘어갈 수 있었다.느낀점위에서 말했던 것처럼 국비교육은 생략해서 혼자 공부하면서 알게 됐던 내용들이 멘토님의 강의에 찰떡 같은 비유와 함께 있는 것을 보면서 국비교육 말고 혼자서 강의로 공부했다면 더 많이 배웠을까 라는 생각이 들었다.개인사유로 인해 금요일에 있었던 백엔드 1차 중간점검에 참여하지 못해서 너무 아쉬웠다. 다음에 있는 중간점검은 꼭 참여해서 멘토님의 이야기를 들으면서 식견을 넓혀야겠다.   

인프런워밍업클럽스터디1기워밍업클럽스터디백엔드

코파

인프런 워밍업 클럽 스터디 1기 FE | 1주차 발자국

목차스터디 참가 계기와 소감 과제 내용앞으로의 방향1. 스터디 참가 계기와 소감 "'HTML, CSS, JS'로 나만의 웹사이트를 만들어 보아요!"라는 유혹적인 문구에 현혹되어 작년 말 웹 개발에 입문하게 되었다. 그리고 작년 크리스마스부터 개강한 모 KDT 국비교육 프론트엔드 부트캠프에 참가하게 되었고, 몇 주 전 수료를 하게 되었다. 4개월이 채 되지 않는 짧은 교육 기간에도 불구하고, 프론트엔드 개발자에게 필수적인 지식은 얼추 쌓을 수 있었다.  하지만 교육과정에서 진행된 두 개의 프로젝트에서 모두 백엔드를 담당하게 되면서 정작 프론트엔드 프로젝트가 하나도 없는 상태로 취업시장에 덩그러니 놓여지게 되었다. 백엔드 프로젝트 리팩토링이나 이력서 작성 등을 고민하며 시간을 낭비하고 있던 와중, 마침 인프런에서 진행하는 스터디를 발견하였다. 이 스터디에 참가하기 위해서는 무려 6만 6천원이라는 비용을 지불해야 했다. 강의 자체보다는 돈을 내고 스터디에 참여한다는 강제성이 큰 자극이 되어 꾸준한 학습을 진행하는 데 도움이 될 것이라고 판단하였다(강의가 수강료에 비해 좋지 않다는 의미가 절대 아니다). 실제로 기한이 주어지는 과제를 통해 평소라면 시작조차 하지 않았을 것들을 구현해보았다. 과제를 수행하면서 문제 정의와 해결 능력을 키울 수 있었다. 또한, 다른 참가자들이 꾸준히 참여하는 모습을 보는 것만으로도 자극을 받는다. 개발초보 취준생인 나부터 회사다니면서 공부하는 경력자분들, 그리고 공부하는 대학생분들까지 모두가 열심히 노력하는 모습을 보며 동기부여에 큰 도움이 되었다. 남은 기간 동안 목표 달성에 힘써야겠다.2. 과제 내용 1) 음식 메뉴https://www.inflearn.com/blogs/7678과제 설명 : 단골 카페인 쉬즈베이글의 메뉴를 만들어보았다. 카테고리별로 나누는 기능(필터링)을 구현하는 것이 핵심이었다.힘들었던 점 : 여태껏 쉬다가 오랜만에 바닐라 자바스크립트를 사용하려고 하니 그 자체가 버거웠다. 특히 자바스크립트로 HTML 요소들을 동적으로 생성하는 부분에서 많은 시간을 소모하였다.소감 : HTML 요소를 동적으로 생성하는 코드를 많이 작성하였다. 이게 효율적인지 의문이 들어서 시간날 때 연구를 해볼 것이다. 2) 가위바위보 게임https://www.inflearn.com/blogs/7768과제 설명 : 가위, 바위, 보 중 하나를 내면 게임이 진행된다. 각 회차별 남은 횟수 및 점수, 마지막 승부 결과와 리셋 버튼까지 구현해보았다.힘들었던 점 : 게임 로직은 단순하여도 여러 요소들을 화면에 렌더링하는 코드를 작성하는 것이 익숙하지 않아서 오래 걸렸다. 단순히 자바스크립트로 가위바위보 게임을 작성하라고 하면 쉬울텐데, 화면에 있는 여러 가지 요소들을 고려해야한다는 점에서 프론트엔드 개발이 쉽지 않다고 느낀다.소감 : Math.random을 활용하여 랜덤 생성하는 것이 어려워서 좀 연습을 해야할 것 같다. 3) 퀴즈(개발 진행중으로 링크 업로드하지 않음 ^^ ><)과제 설명 : 퀴즈 앱은 욕심을 많이 부려서 추가한 기능이 많기 때문에 아직 100% 완성하지는 못하였다. 현재 OX퀴즈에 있었던 큰 이슈를 해결한 상황이다.힘들었던 점 : 과제 중 이것이 가장 어려웠다. 일단 데이터를 불러와서 렌더링해야하는 점부터 어려웠고, 30문제의 데이터 중 10개를 뽑는 로직부터 작성하기 힘들었다. 다음 단계로 넘어갈 때 문제, 정답, 해설을 모두 업데이트 해야하는데, 오류가 매우 많아서 어떤 오류가 있었는지 기억이 잘 나지도 않는다.소감 : 처음부터 로직을 분리하여 추상화된 코드를 작성하고 싶은데 마음 같지 않다. 4) 책 목록https://www.inflearn.com/blogs/7759과제 설명 : 다른 이름의 투두리스트이다. 과제에는 삭제하는 것만 나온 것 같은데, 제대로 된 투두리스트를 만들어본 적이 없어서 수정, 삭제, 추가 기능 (임시저장, CSV 파일 변환, 전체 초기화)도 구현해 보았다.힘들었던 점 : html에서 <table>태그를 처음 다루어보아서 낯설었고, CSV 파일 변환 기능 구현할 때 이슈가 많아서 별도로 정리해두었다.소감 : 일단 CRUD부터 정확하고 빠르게 구현한 후, 추가기능을 고도화하는 방향으로 진행해아 할 것 같다. 리액트도 CRUD부터 빠르고 정확하게 만드는 연습을 해야겠다. 5) 비밀번호 생성https://www.inflearn.com/blogs/7745과제 설명 : 최대 네 가지 조건을 만족하는 비밀번호를 생성하는 어플을 만드는 것이었다. 힘들었던 점 : 기본 아이디어는 네 가지 조건에 해당하는 문자열을 각각 변수에 담아두고, 해당 조건을 체크하면 문자열들을 합친 후 랜덤으로 인덱스를 생성하여 추출하는 방식으로 하였다. 그런데 이러한 경우 체크된 조건에 해당하는 문자가 하나도 없을 수 있기 때문에, 체크된 조건의 문자열은 무조건 무작위로 1개를 뽑은 후에 진행하는 로직으로 변경하였다. 이 부분이 어려웠다.소감 : 배열과 관련된 고차함수를 잘 다루는 것이 중요한 것 같다. 아직 많이 부족해서 꾸준히 공부하려고 한다. 전체 소감변수 선언시 const, let과 scope의 중요성을 명확하게 깨달았다. 이 부분과 관련해서 오류가 많이 났었다. 함수를 작성하더라도 반환값을 리턴하는 것을 간과하거나, 클래스를 생성할 때 constructor가 초기 실행 시점에 작동한다는 점 등 세부사항에 대한 고려가 필요함을 알게 되었다.코드를 작성하면서 로직을 분리하는 것이 얼마나 중요한지를 실감하게 되었다. 코드에 반복되는 패턴이 보인다면 이를 상위 수준으로 추상화하여 정리하는 것이 필요하다. 말은 쉽지만, 내 수준에서는 징그럽게 어렵다.GitHub Finder, 타이핑 테스트, 퀴즈 앱은 화요일까지 완성하려고 한다.3. 앞으로의 방향 1) 수료를 위한 필수적인 목표 바닐라 JS 과제 3개 (완료)리액트 과제 3개발자국 3회 작성 (매주 일요일) : - 발자국에 수업 내용도 정리하기 - 이번주는 수업 내용 정리를 못해서 다음주부터 진행할 예정그룹스터디 2회 참여 및 공부 내용 발표 2) 추가 목표 코드 리팩토링: 기능 개선 및 추가, CSS 적용 (특히 라이브러리 활용), 로직 분리 등을 통한 코드 개선배포 및 정리: 효울적인 코드 고민해보기 

웹 개발워밍업클럽FE발자국1주차

lar

[인프런 워밍업 클럽 스터디 1기] 첫번째 발자국

1. 1주차 학습한 강의 내용 1일차(1강~5강)1. 새로운 프로젝트 시작하기Spring Initializr 사용하기https://start.spring.io/새로운 프로젝트를 시작할 때 사용하면 된다.의존성 : 프로젝트에서 사용하는 라이브러리와 프레임워크를 의미한다.라이브러리 : 프로그래밍을 개발할 때 미리 만들어져 있는 기능들을 가져와서 사용하는 것을 의미한다.프레임워크 : 프로그래밍을 개발할 때 미리 만들어져 있는 구조에 코드를 가져와서 넣는 것을 의미한다.2. @SpringBootApplication과 서버@SpringBootApplicationpackage com.group.libraryapp; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class LibraryAppApplication { public static void main(String[] args) { SpringApplication.run(LibraryAppApplication.class, args); } }@SpringBootApplication : 어노테이션, 스프링 부트를 자동으로 설정이 가능하다.Class : 메인 메소드로 구성된다.SpringApplication.run(LibraryAppApplication.class, args) : 실제 스프링 부트 애플리케이션을 시작한다는 의미를 가진 코드이다.서버(Server)란?기능을 제공하는 것을 의미한다.어떠한 기능을 제공하는 프로그램을 의미한다.그 프로그램을 실행시키고 있는 컴퓨터를 의미한다.3. 네트워크란 무엇인가?IP : 컴퓨터의 주소를 의미한다.Domain Name(도메인 네임) : 외우기 어려운 IP 대신 외우기 쉬운 이름으로 변환한 것을 의미한다.DNS : IP 244.66.51.9 = 도메인 네임 spring.com, 이러한 체계를 의미한다.port(포트) : 사용하는 프로그램 데이터를 받는다.4. HTTP와 API란 무엇인가?HTTP란?인터넷에서 데이터를 주고 받을 때 하는 표준, 약속을 의미한다.예) 운송장 표준 - 요청하는 행위, 받는 사람, 항목(자원), 세부조건행위와 자원은 운송장을 보내기 전에 약속을 해야 한다.HTTP 요청GET 요청GET /portion?color=red&count=2 Host: spring.com:3000 //의미 - 내놓아라 파란집 둘째, 포션 빨간색 2개 GET(HTTP Method) : 요청을 받는 컴퓨터에게 요청하는 행위(데이터 요청)/portion(Path) : 받을 항목(자원)? : 구분기호color=red : 자원의 세부조건(Query)& : 구분기호count=2 : 자원의 세부조건(Query)Host: spring.com:3000 : HTTP 요청을 받는 컴퓨터와 프로그램 정보POST 요청POST/oak/leather Host: spring.com:3000 오크가죽정보 //창고에 넣어라 빨간집, 오크가죽 POST : 요청을 받는 컴퓨터에게 요청하는 행위(데이터 저장)/oak/leather : HTTP 요청을 받는 컴퓨터에게 원하는 자원Host: spring.com:3000 : 어떤 컴퓨터에 어떤 데이터를 받을지 정보오크가죽정보 : 실제 저장할 오크 가죽 정보(데이터, Body)데이터를 보내는 2가지의 방법쿼리 : GET에서 사용한다.바디 : POST에서 사용한다.다양한 HTTP MethodGET : 데이터 요청, 쿼리 사용POST : 데이터 저장, 바디 사용PUT : 데이터 수정, 바디 사용DELETE : 데이터 삭제, 쿼리 사용API(Application Programming Inteface)란?정해진 약속을 통해 특정 기능을 수행하는 것을 의미한다.HTTP 응답정보 처리해서 응답 보내기(200 OK) -> 200 OK : 정보가 잘 저장되었다는 의미이다.저장이라는 기능을 수행한다.💡 요청에 대한 응답을 제공한 컴퓨터는 서버(Server)를 의미한다.💡요청한 컴퓨터는 클라이언트(Client)를 의미한다.상대 코드응답에 들어가는 숫자를 의미하며, 매우 다양하다.어떠한 상태인지 알려주는 코드이다.상대 코드의 종류200 OK : 요청이 성공했다는 의미이다.300 Moved Permanently : 다른 곳으로 옮겨가라는 의미이다.404 NotFound : 요청한 내용을 찾을 수 없다라는 의미이다.500 Internal Server Error : 내부에 문제가 발생했다는 의미이다.5. GET API 개발하고 테스트 하기덧셈 APIHTTP Method -> GETHTTP Path -> /add쿼리(key와 value) -> int number1 / int number2API의 반환 결과 -> 숫자 - 두 숫자의 덧셈 결과GET API 개발 데이터의 흐름Postman에서 ?number1=100&number2=200(쿼리) 스프링 부트에서 보내면 값을 보고 객체로 만들어둔 Calculator, Add, Request에다가 값을 넣는다.그 객체를 Controller, API의 진입지점에 보내준다.정보를 전달하는 역할의 객체 : DTO(Data Transfer Object)Postman에서 send를 하면, HTTP 요청 -> 스프링 부트 서버로 도착 -> API 진입지점을 거쳐 /Add 통과 후 DTO request 함수를 실행한다.return -> 응답 생성 -> Postman에게 전달 -> Postman에서 결과를 보여준다. 2일차(6강~9강)1. POST API 개발 및 테스트하기POST API에서 데이터 받을 경우HTTP Body 사용한다.JSON으로 데이터를 받는다.사용되는 문법 -> JSONJSON이란?객체 표기법을 의미하며, 무언가를 표현하기 위한 형식이다.JSON 문법{}중괄호를 사용한다.{}중괄호 안에 "key":value로 표기한다.속성은 ,로 구분한다.추가적으로 다른 JSON 문법을 작성할 수 있다.{ "name":"김철수", "age":50 } 곱셈 APIHTTP Method -> POSTHTTP Path -> /multiplyHTTP Body(JSON) -> {"number1":숫자,"number2":숫자}API의 반환 결과 -> 숫자(곱셈 결과)POST API 개발 데이터 흐름데이터를 전달해주는 객체인 DTO 생성POST API 개발Body 사용 시 @RequestBody 어노테이션을 사용한다.JSON을 CalculatorMultiplyRequest 객체로 전환해준다. 2. 유저 생성 API 개발 및 테스트하기도서 관리 애플리케이션의 요구사항사용자도서관 사용자 등록(이름 필수, 나이 선택)도서관 사용자 목록 확인도서관 사용자 이름 수정도서관 사용자 삭제책도서관 책 등록 및 삭제도서관 사용자 책 대여다른 사람이 대여 시 대여 불가능도서관 사용자 책 반납도서관 사용자 등록하기유저 생성 API 조건HTTP Method : POSTHTTP Path : /userHTTP Body (JSON)JSON { "name": String (null 불가능), "age":Integer } 결과 반환 X(HTTP 상태 200 OK이면 충분하다.)유저 생성 API 개발 데이터 흐름Body를 객체로 표현할 DTO 생성유저를 저장하기 위한 객체 생성유저 생성 API 개발POST user 호출 -> 함수 실행 -> Body에 이름과 나이가 들어오면 객체로 매핑한다.새로운 유저를 만들 때 사용되는 Requset -> 생성된 유저 객체가 List에 저장 -> 함수가 예외없이 완료되면 응답코드 200 OK로 반환한다.3. 유저 조회 API 개발 및 테스트하기유저 조회 API 조건HTTP Method : GETHTTP Path : /user쿼리 : 없음결과 반환 (JSON)JSON { "name": String (null 불가능), "age":Integer } 유저 조회 API 개발 데이터 흐름데이터를 담아 줄 DTO 생성유저 조회 API 개발User List 생성 -> List에 들어있는 유저들이 1개씩 돌면서 UserResponse 형태로 반환한다.결과 리스트에 추가 -> responses로 반환한다. 3일차(10강~13강)1. 컴퓨터의 핵심 부품 이해하기서버 유저 정보가 왜 남아있지 않는지 이해하기 위해 알아보자.CPU : 연산RAM : 임시 기억장치DISK : 장기 기억장치2. Database와 MYSQLDatabase란?데이터를 구조화시켜 저장하는 것을 의미한다.RDB (Relational Database) - MySQL : 데이터를 표처럼 구조회 시켜 저장하는 것을 의미한다.SQL(Structured Query Language) : 표처럼 구조화된 데이터를 조회하는 언어이다.3. MySQL에서 Table 생성하기데이터베이스 생성create database [데이터베이스 이름]; 데이터베이스 목록 확인show databases; 데이터베이스 삭제drop database [데이터베이스 이름]; 데이터베이스 안으로 들어가기use [데이터베이스 이름]; 테이블 목록 확인show tables; 테이블 생성create table [테이블 이름] ( [필드1 이름] [타입] [부가조건], [필드1 이름] [타입] [부가조건], ... primary key([필드 이름]) ); 테이블 생성 예시create table fruit ( id bigint auto_increment, name varchar(20), price int, stocked_date date, primary key (id) ); auto_increment : 데이터가 없어도 1부터 1개씩 증가하며, 자동 기록된다.primary key : 유일한 키를 의미하며, id라는 필드를 지정한다.테이블 삭제drop table [테이블 이름]; => 해당 SQL를 DDL(Data Definition Language)이라고 정의한다.MYSQL 타입의 종류정수 타입tinyint : 1바이트int : 4바이트bigint : 8바이트실수 타입double : 8바이트 정수decimal(A, B) : 소수점을 B개 갖고 있는 전체 A자릿수 실수문자열 타입char() : ()글자가 들어갈 수 있는 문자열varchar() : 최대 ()글자가 들어갈 수 있는 문자열날짜, 시간 타입date : 날짜, yyyy-MM-ddtime : 시간, HH:mm:ssdatetime : 날짜와 시간을 합친 타입, yyyy-MM-dd HH:mm:ss4. Table 데이터 조작하기생성, 조회, 수정, 삭제 방법(CRUD)생성 : Create읽기 : Read수정 : Update삭제 : Delete데이터 삽입insert into [테이블 이름](필드1 이름, 필드2 이름) values (값1, 값2, ...) 데이터 삽입 예시insert into fruit (name, price, stocked_date) values ('사과', 1000, '2023-01-01'); ()안의 필드와 값의 순서가 중요하기 때문에 순서대로 작성해야 한다.id는 지정하지 않아도 auto_increment가 자동으로 생성해준다.데이터 조회select * from [테이블 이름]; select * from [테이블 이름] where [조건]; 데이터 조회 예시select name, price from fruit; select * from fruit where name = '사과' and price <= 2000; 테이블명 대신 필드 이름도 가능하며, 여러개를 넣을 수도 있다.조건을 넣어서 조회도 가능하다. (and, or, =,>=,<=, !=, between, in, not 등이 있다.)데이터 수정update [테이블 이름] set 필드1이름=값, 필드2이름=값, ... where [조건]; 데이터 수정 예시update fruit set price = 1500 where name = '사과'; 조건을 붙이지 않으면 모든 데이터가 업데이트 되기 때문에 주의 해야 한다.데이터 삭제delete from [테이블 이름] where [조건]; 데이터 삭제 예시delete from fruit where name = '사과'; 조건을 붙이지 않으면 모든 데이터가 삭제 되기 때문에 주의 해야 한다.=> 해당 SQL를 DML(Data Manipulation Language)이라고 정의한다.5. Spring에서 Database 사용하기Database 설정 파일 추가application.yml 파일 생성spring: datasource: url: "jdbc:mysql://localhost/library" username: "root" password: "" driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://Host/접근DB명username: MySQL에 접근하기 위한 계정명password: MySQL에 접근하기 위한 비밀번호driver-class-name: DB에 접근 시 사용할 프로그램 4일차(14강~16강)1. 사용자 수정 API, 삭제 API 개발 및 테스트하기사용자 수정 API 조건HTTP Method : PUTHTTP Path : /userHTTP Body (JSON){ "id": Long, "name": String } 결과 반환 X (HTTP 상태 200 OK이면 충분하다.)사용자 삭제 API 조건HTTP Method : DELETEHTTP Path : /userQuery 사용문자열 name (삭제되어야 하는 사용자 이름)결과 반환 X (HTTP 상태 200 OK이면 충분하다.)사용자 수정 및 삭제 API 개발사용자를 수정하기 위한 DTO 추가사용자 수정/삭제 API 개발사용자 수정 API, 삭제 API 예외처리 하기존재하지 않는 사용자를 수정하거나 삭제하려고 해도 응답코드 200 OK가 나온다.> 예외처리해야 한다.데이터 존재 여부를 확인하고 예외처리 하기사용자 수정/삭제 API 예외처리 개발id를 기준으로 사용자가 존재하는지 확인하기 위해 SELECT 쿼리 작성한다.SQL을 DB에 전송해서 데이터가 있는지 확인한다.SELECT SQL의 결과가 있으면 0 반환, ? 값 id를 삽입한다.0은 최종적으로 List로 반환한다. 사용자가 존재하지 않을 경우 예외처리한다.사용자가 존재하지 않을 경우예외처리한 결과, 내부에 문제가 있다는 오류가 발생했다. 5일차(17강~18강)1. 좋은 코드(Clean Code)가 왜 중요한가?코드는 요구사항을 표현하는 언어이다. 좋은 코드는 코드만 보고도 의미를 파악을 할 수 있다.안 좋은 코드가 쌓이면, 시간이 지날수록 생산성이 낮아진다.Clean Code함수는 최대한 작게 만들고, 1가지 일만 수행하는 것이 좋다.클래스는 작아야 하며, 하나의 책임만을 가져야 한다.2. Controller, Service, Repository 분리하기Controller의 함수 1개가 하고 있던 역할API의 진입 지점으로서 HTTP Body를 객체로 변환한다 -> Controller현재 유저가 있는지 없는지 등을 확인하고 예외처리를 해준다. -> ServiceSQL을 사용해 실제 DB와의 통신을 담당한다. -> Repository역할 분리 구조Controller : API와 HTTP 관련 역할 담당Service : 분기 처리 및 로직 담당Repository : DB와의 접근을 담당각 역할을 분리하여 수행하는 계층으로 이루어진 구조를 계층화 아키텍쳐(Layered Architecture)라고 한다.JdbcTemplate 변수를 선언하고 생성자를 통해 UserRepository를 인스턴스화하는 시점에 JdbcTemplate을 넣어주도록 변경한다.2. 미션첫 번째 과제(1일차)나만의 어노테이션을 만들 수 있었다는 걸 알게 되었고, 어떠한 상황에서 정해진 어노테이션만 사용했었는데, 만드는 방법을 알게 되어 좋았다.두 번째 과제(2일차)3번째 문제에서 배열로 처리했는데, 배열보다는 리스트로 하는 게 더 좋다는 피드백 댓글을 보고 리스트로 적용해서 구현해보고, 다른 방법들도 알게 되어 좋았다.세 번째 과제(3일차)람다식에 대해 깊게 공부한 적은 없었는데, 이번 과제를 하면서 람다식에 대한 도입 배경, 방법 등을 알게 되어 좋았다.3. 회고일주일이 정말 금방 지나간 느낌이다. 과제를 하면서 스스로 고민해보고 구현하면서 성장할 수 있는 시간을 갖게 되어 좋았다. 다른 일도 겹치면서 아직 4,5일차 과제를 완료하지 못했지만 기간 안에 제출하도록 노력해야겠다. 헷갈리는 부분들을 복습하면서 다음주엔 더 분발해야겠다!

백엔드발자국회고워밍업1주차

Edun

[1주차] 인프런 워밍업 클럽 스터디 FE 1기 발자국

1주차 회고록 작성.<강의>- 따라하며 배우는 자바스크립트 A-Z (Section0~1)<과제>- 음식 메뉴 App 만들기 [버거킹 메뉴 앱]: Javascript의 html 속성을 통해 각 노드의 요소마다 Button별로 Filtering된 Data를 넣어주기.<느낀점>1) 내게는 너무 낯선 Javascript2) 자유분방-예측불가-코드리뷰가 막막한 녀석. . .3) 어떻게든 돌아가도록 프로그램을 만들기 위해 탄생한 JavaScript라니. . .4) 이 녀석을 재밌게 만들어준 동료들(뀨님,꼉님, 쏘님) 사랑합니다 핫투.[JavaScript 기초]Console 객체IDE 설치VS codeWebStormVS code - Live Server 설치웹 프로젝트를 미리 볼 수 있도록 로컬 서버를 호스팅하는 확장 프로그램script.js - console.log크롬 개발도구(F12) Console 창에 출력됨개발시 어떠한 식으로 진행되는지 Console로 출력해서 알아보면 용이함어디서, 어떻게 에러가 났는지 출력을 할때 log사용함console.log('Hello,World'); console.log('1243'); console.log(true); var greeting = 'hello!'; console.log(greeting); console.log({a: "a", b: "b"}); console.table({a: "a", b: "b"}); console.error('Error!'); console.warn('Warning!!'); console.time('Hello'); console.time(1); console.time(2); console.time(3); console.time(4); console.time(5); console.time(6); console.time(7); console.timeEnd('Hello'); 변수 선언 : var, let, const자바스크립트 코드 작성브라우저 - 개발도구에서 바로 사용 가능IDE - VSCode 활용변수 선언 방식 / 참조범위 / 호이스팅호이스팅 : 인터프리터 언어 특성상, 호이스팅이 제공됨 (변수 끌어올려서 사용하는 것)| 변수 | 중복 | 재할당 | 유효한 참조 범위 (Scope) | 호이스팅 (변수 끌어올림) | | --- | --- | --- | --- | --- | | var | O | O | 함수 레벨 | 선언 : undefined 자동 할당 (초기화 전) 할당 : 값 할당 | | let(ES6) | X | O | 블록 레벨 | 선언 : undefined 할당 X (TDZ : Temporal Dead Zone) | | const(ES6) | X | X | 블록 레벨 | 선언 : undefined 할당 X (TDZ : Temporal Dead Zone) |// var type : 선언 및 할당 여러번 가능 (자유도 높음) // : 유지보수 하기 힘듦. var A = 1; console.log(A); var greeting = 'hello'; console.log(greeting); var greeting = 'hi'; console.log(greeting); greeting = 'how are you?'; console.log(greeting); // let type : 중복선언 X, 할당 가능 let ttt = 'hi, halo'; console.log(ttt); //let ttt 'haha'; // error. ttt = 'papapapa'; console.log(ttt); // const type : 중복 && 할당 X // : constant (상수) 약자 const damn = 'yess'; console.log(damn); //const damn = 'ttt'; //error. //damn = 'yesfds'; //console.log(damn); //error. //------------- 02. Scope //------------- 01) var 함수 레벨 스코프 function func() { if(true) { var a = 'a'; console.log(a); } console.log(a); } func(); //------------- 02) let,const 블록 레벨 스코프 function func2() { if(true) { let a = 'a_let'; console.log(a); } } func2(); //------------- 03. 호이스팅 //------------- 01) var 호이스팅 : undefined //------------- 02) let, const 호이스팅 : error. console.log(seelping); var seelping = '자고싶다'; // undefined let seelping = '자고싶다'; //error. //------------- 03) 함수 호이스팅 : 정상출력. func3(); function func3() { console.log('hosting test'); } 자바스크립트 타입원시타입 : Boolean, String, Numeric, Null, undefined, Symbol불변성에 저장됨고정 크기로 Call Stack에 저장됨실제 데이터가 변수에 할당됨참조타입 : Object, Array, Class, Functions실제 데이터는 Heep에 저장됨데이터 크기가 정해지지 않고 주소값이 Call Stack에 저장됨자바스크립트 = 동적 타입느슨한 타입동적 언어변수는 타입과 연결되지 않음모든 타입의 값으로 할당(및 재할당) 가능string → boolean → numeric 가능한 것//------------------------ 원시 타입 // 문자열 String const name = 'Edun'; // Number const age = 38; // Boolean const hasJob = true; // null const car = null; // undefined let anything; // Symbol const sym = Symbol(); //------------------------ 참조 타입 // Array 배열 : 객체의 하나의 형태 const hobbies = ['wailing', 'books']; // Object 객체 const addr = { province : '부산광역시', city : '남구' } console.log(typeof hobbies); console.log(Array.isArray(hobbies)); 자바스크립트 타입변환자바스크립트 함수 사용 변환let val; // Nuber to String val = String(111); val = String(8 + 4); // Boolean to String val = String(false); // Date to String val = String(new Date()); // Array to String val = String([1,2,3,4,5]); // toString() val = (5).toString(); // String to number val = Number('1'); val = Number(true); val = Number(false); val = Number(null); val = Number([1,2,3]); // NaN = Not a Number val = parseInt('111.40'); val = parseFloat('111.40'); console.log(val); console.log(typeof val); console.log(val.length); 자바스크립트 자체에 의해 자동 변환const val1 = 2; const val2 = String(3); const sum = val1 + val2; console.log(sum); // string으로 자동변환. console.log(typeof sum); 자바스크립트 연산 및 Math Objectconst num1 = 20; const num2 = 10; let val; // 산수 연산 val = num1 + num2; val = num1 * num2; val = num1 - num2; val = num1 / num2; val = num1 % num2; // 나머지 연산자 // Math Object //--------------------------------- 속성 val = Math.E; // 속성 val = Math.PI; // 속성 //--------------------------------- 메서드 val = Math.round(2.4); // 가까운 정수로 리턴 val = Math.ceil(2.4); // 무조건 올림 val = Math.floor(2.8); // 무조건 내림 val = Math.abs(-2); // 절댓값 val = Math.min(2,3,4,5,6,7,8,-1); val = Math.max(2,3,4,5,6,7,8,-1); val = Math.random(); // 0~1 사이에서 return. // 1~20 사이 랜덤 숫자 val = Math.floor(Math.random() * 20 + 1); //+1 필수. console.log(val); Template LiteralsTemlate Literals : javascript에서 backtick() 문자를 사용하여 문자열을 표현한 템플릿쉬운 줄바꿈‘\n’ → 실제 Enter 적용문자열 내부에 표현식을 포함할 수 있음‘+{a+b}+’ → 보간법 ${a+b}백틱(backtick) ⇒ ‘ ` '로 사용Loopsfor 코드 블록을 여러 번 반복 for/in 객체의 속성을 따라 반복 while 지정된 조건이 true 인 동안 코드 블록을 반복 do/while while 루프의 변형 조건이 true인지 검사하기 전에, 코드 블록 한 번 실행 후 조건이 true인 동안 루프 반복for vs forEachfor forEach 원래 사용되었던 접근 방식 배열 요소를 반복하는 새로운 접근 방식 breack 사용 가능 breack 사용 불가능 빠름 for보다 느림 비동기 await 작동 비동기 await 작동 애매함// for문 for(let i=0; i < 10; i++){ if(i === 3){ console.log('It is 3'); continue; } if(i === 5){ console.log('5 Stop the loop.'); break; } console.log('Number ' + i); } // for/in 문 const user = { name: 'Edun', province: '부산광역시', city: '남구' } for(let x in user){ console.log(`${x} : ${user[x]}`); } // while 문 let i = 0; while(i < 10){ console.log('Numer ' + i); i++; } // do/while 문 let i = 0; do { console.log('Number ' + i); i++; } while(i < 10); //배열을 Loop로 이용해서 컨트롤 해주기 const locations = ['서울', '부산', '경기도', '대구']; for(let i = 0; i < locations.length; i++){ console.log(locations[i]); } locations.forEach(function (location, index, array){ console.log(`${index} : ${location}`); console.log(array); }); // console.log(locations);   

프론트엔드JavaScripthtmlcssinflearn인프런워밍업스터디

희희

[인프런 워밍업 클럽 스터디 1기] BE 1주차 회고

첫번째 발자국 인프런 워밍업 클럽 스터디에 참여하여 일주일을 보낸 후 쓰는 첫번째 회고록. Section 1 - 생애 최초 API 만들기JVM자바 가상 머신의 약자os 별로 존재한다.바이너리 코드들을 읽고 검증한다.JRE자바 실행 환경의 약자JRE = JVM + 자바 프로그램 실행에 필요한 라이브러리 파일 등JVM의 실행 환경을 구현JDK자바 개발 도구의 약자JDK = JRE + 개발을 위한 도구(통합 개발 도구)컴파일러, 디버그 도구 등이 포함되어 있다.여러 버전이 있고, 각 버전별로 새로운 기능이 추가되거나 기존 기능이 사라진다.여러 종류가 있고, 기능 자체는 동일하나 성능과 비용에 약간의 차이가 있을 수 있다. 빌드 : 소스코드 파일을 컴퓨터에서 실행할 수 있는 독립 SW 가공물(Artifact, 독립적인 하나의 파일)로 변환시키는 과정실행 : 작성한 코드를 컴파일을 거쳐 작동시켜보는 것(독립 SW 가공물이 나올수도 있고, 나오지 않을 수도 있음)빌드 과정 자동화와 외부 라이브러리 관리를 위해 빌드 툴이 사용되며, 자주 사용되는 자바 빌드툴에는 maven, gradle이 있다. 어노테이션자동으로 설정/기능을 동작하게 하는 것@ + (어노테이션으로 만들어둔) 클래스 이름 서버 : 어떤 기능을 제공하는 프로그램. 또는 그 프로그램을 실행시키고 있는 컴퓨터클라이언트 : 서버에 어떤 기능을 요청하는 프로그램. 또는 그 프로그램을 실행시키고 있는 컴퓨터HTTP : 컴퓨터가 네트워크를 통해 다른 컴퓨터와 데이터를 주고받을 때 사용되는 통신 규약(중 하나)HTTP Method : HTTP 요청을 받는 컴퓨터에게 요청하는 행위(GET, POST, PUT, DELETE 등)요청을 받는 컴퓨터(IP 주소 / 도메인)와 프로그램(port) 정보Path : HTTP 요청을 받는 컴퓨터에게 원하는 자원Query : 자원의 세부 조건(조건이 여러개면 &로 구분)Body(JSON) : 저장할 자원의 정보JSON : 객체 표기법. 중괄호 안에 "key": value로 표기하며, 속성 각각은 ,로 구분한다. 요청에 대한 HTTP 응답200 OK (요청이 잘 처리됨)300 Moved Permanently (다른 곳으로 옮겨가라)404 NotFound (요청한 것을 찾을 수 없음)500 Internal Server Error (우리 내부에 문제가 생김)응답에는 추가 정보(바디)를 담을 수도 있음 API 정해진 약속을 하여 특정 기능을 수행하는 것클라이언트와 서버는 HTTP를 주고 받으며 기능을 동작하는데 이때 정해진 규칙API의 구성 요소(명세)HTTP MethodHTTP PathQuery(key와 value)API의 반환 결과 @RestController: 주어진 클래스를 Controller(API의 입구)로 등록한다 -> 현재 클래스를 API의 진입 지점으로 만들어줌@GetMapping("/add"): 아래 함수를 HTTP Method가 GET이고 HTTP Path가 /add인 API로 지정한다.@RequestParam: 주어지는 쿼리를 함수 파라미터에 넣는다 -> 같은 이름을 가진 쿼리의 값이 함수의 argument로 들어온다@RequestBody: HTTP Body 안에 담긴 JSON을 DTO 객체로 변환 (DTO : 정보를 전달하는 역할의 객체) Section 2 - Database 조작하기Database의 필요성: API를 통해 생성된 정보는 단기 기억장치인 RAM에 기록되는데, RAM에 기록된 정보는 서버가 종료되면 사라지기 때문에 DISK에 장기 저장하기 위해 DB를 사용한다. Database : 데이터를 구조화해서 저장하는 것RDB(Relational DB) - MySQL : 데이터를 표처럼 구조화해서 저장하는 DBSQL(Structured Query Language) : 표처럼 구조화된 데이터를 조회,저장 등 조작하는 언어-> MySQL을 사용 DDL(Data Definition Language) : 데이터를 정의하는 언어데이터베이스 만들기 : create database [데이터베이스 이름];데이터베이스 목록 보기 : show databases;데이터베이스 지우기 : drop database [데이터베이스 이름];데이터베이스 안으로 들어가기 : use [데이터베이스 이름];(특정 데이터베이스 안으로 들어간 후)테이블 목록 보기 : show tables;테이블 만들기 :create table [테이블 이름] ([필드1 이름] [타입] [부가조건],[필드2 이름] [타입] [부가조건],...primary key ([필드이름]));테이블 제거하기 : drop table [테이블 이름];DML(Data Manipulation Language) : 데이터를 조작하는 언어데이터를 넣는다 = 생성, create데이터를 조회한다 = 조회(읽기), retrieve of read데이터를 수정한다 = 업데이트, update데이터를 삭제한다 = 제거, delete-> CRUD데이터 넣기INSERT INTO [테이블 이름] (필드1이름, 필드2이름, ...)VALUDES(값1, 값2, ...)필드 이름과 값의 순서가 맞아야 한다명령어는 소문자로 써도 상관 없다auto_increment로 지정된 필드값은 지정해주지 않아도 자동으로 설정된다데이터 조회하기SELECT * FROM [테이블 이름];* 대신 필드 이름을 넣을 수 있다. 여러 개 넣는 것도 가능하다.SELECT * FROM [테이블 이름] WHERE [조건];where을 이용해 필터(조건)을 걸 수 있다.AND 또는 OR을 이용해 조건을 이어 붙일 수 있다.조건에는 =, <= 외에도 !=, <, >, >=, between, in, not in 등이 있다.BETWEEN [범위의 시작값] AND [범위의 끝값] : 양끝값을 포함한 범위 내의 값들만 가져온다.IN(조건1, 조건2) : 여러 조건을 한 번에 표시할 때 사용NOT IN() : 괄호 안 조건들에 포함되지 않는 데이터만 조회할 때 사용데이터 업데이트하기UPDATE [테이블 이름] SET 필드1이름=값, 필드2이름=값, ...WHERE [조건];where 절을 사용해 [조건]을 붙이지 않으면, 모든 데이터가 변경(업데이트)되니 주의해야 함데이터 삭제하기DELETE FROM [테이블 이름] WHERE [조건];[조건]을 붙이지 않으면 모든 데이터가 삭제되니 주의할 것!Spring에서 Database 사용하기사람이 아닌 스프링 서버가 MySQL 서버에 접근하게 하는 것application.yml 만들고 설정spring: datasource: url: "jdbc:mysql://localhost/library" username: "root" password: "5502" driver-class-name: com.mysql.cj.jdbc.DriverAPI 변경jdbcTemplate을 이용해 SQL을 날릴 수 있다. SQL을 만들어 문자열 변수로 저장한다. 이때 값이 들어가는 부분에 ?를 사용하면, 값을 유동적으로 넣을 수 있다.jdbcTemplate.update()는 INSERT, UPDATE, DELETE 쿼리에 사용할 수 있다(데이터에 변경을 주는 쿼리). 첫 파라미터로는 sql을 받고, ?를 데신할 값을 차례로 넣으면 된다.jdbcTemplate.query(sql, RowMapper 구현 익명클래스) : mapRow라는 함수를 override하고, override한 MapRow 안에서 sql의 실행 결과가 나오면 그 결과들의 데이터를 가져와 UserResponse(dto)로 바꿔준다. Section 3 - 역할의 분리와 스프링 컨테이너클린 코드가 중요한 이유 코드 : 요구사항을 표현하는 언어-> 개발자는 요구사항을 구현하기 위해 코드를 읽고 작성한다.-> 코드를 읽는 것은 필수적이고 피할 수 없으므로, 코드만 보고도 의미를 명확하게 파악할 수 있도록 코드를 작성해야 한다. 클린 코드함수는 최대한 작게 만들고 한 가지 일만 수행하는 것이 좋다.클래스는 작아야 하며 하나의 책임만을 가져야 한다.Controller의 함수 1개를 역할에 따라 분리API의 진입 지점으로써 HTTP Body를 객체로 변환하고 있다. -> Controller의 역할로 남겨둠현재 유저가 있는지, 없는지 등을 확인하고 예외 처리를 해준다. -> Service의 역할로 분리SQL을 통해 실제 DB와의 통신을 담당한다. -> Repository의 역할로 분리 3가지 역할로 구분된 구조controller : API와 HTTP 역할 담당service : 분기 처리, 로직 담당repository : DB와의 접근 담당* controller는 service를 사용하고, service는 repostory를 사용함** DTO는 계층 간의 정보를 전달하는 역할(여러 계층을 왔다갔다 함)-> 이런 구조를 Layered Architecture라고 한다!  회고인프런 워밍업 클럽 스터디에 참여한지 벌써 일주일이 지났다. 이번주에 다른 일들이 많이 겹쳐 내 생각보다 더 힘들었지만, 혼자서 공부하는 것보다 이점이 훨씬 많았다. 진도표에 매일 공부할 분량이 체계적으로 정해져 있어 내가 별도로 학습 계획을 짜지 않아도 계획적으로 공부할 수 있었다. 여러명이 함께 강의를 수강하는 스터디 방식이라 강의 듣는 것을 미루지 않고 진도표에 맞춰 학습할 동기부여가 되었다. 추가적으로 주어지는 과제를 통해 배운 내용에 대해 스스로 학습하고 정리할 수 있는 것도 좋았다. 강의 내용도 매우 흥미로웠다. 자바와 스프링에 대한 기초 지식부터, 백엔드 개발에 필요한 서버 관련 내용까지 차근차근 정리할 수 있었다. 또한 API 설계 및 개발 과정을 실습으로 진행하며 각 기능이 어떻게 동작하고 구현되는지 직접 코딩을 하며 익혔다. 다른 일들이 겹쳐 과제를 놓치기도 하고 실습 중 자바에 대한 이해가 부족하다는 것을 느껴 조금 아쉬운 1주차였지만, 2주차부터는 좀 더 많은 시간을 투자하고 자바에 대한 학습도 병행하며 더 충실한 일주일을 보낼 수 있도록 노력할 것이다.

백엔드인프런워밍업클럽스터디1기

[인프런 워밍업 클럽 1기 BE] 1주차 발자국

 인프런 워밍업 클럽 1기 스터디 첫 주가 마무리 되었다. 학습 요약 및 회고, 미션 진행 과정과 회고, 첫 주를 마무리한 소감 및 앞으로의 각오 순으로 간략하게나마 첫 발자국을 작성한다. 첫 주의 학습 요약 및 회고진도표를 충실히 따랐다면 18강까지 학습이 완료 되어야 했지만 지난 한 주간 사정이 여의찮아 진도가 꽤 뒤쳐졌다. 발자국 작성 시점에서 수강 완료한 9강까지만 작성하겠다. 2주차에는 최대한 시간을 내어 진도율을 따라잡고자 한다. 섹션 0강의 소개와 준비본격적인 시작에 앞서 강의를 위해 준비하는 단계를 가졌다. Java와 인텔리제이, git은 설치되어 있었지만 PostMan이라는 api 테스트 툴을 처음 접해보았는데 다음 섹션에서 언급하겠지만 상당히 유용하고 편리하다. DBMS 역시 오라클만 사용해 보았기 때문에 영상을 따라 MySQL을 설치했다. 영상으로 명료하게 안내해 주셨기 때문에 프로그램 설치와 프로젝트 환경 설정에 어려움이 없었다. '프로젝트를 시작하는 첫 번째 방법' 영상에서는 올려주신 파일을 통해 Gradle 프로젝트를 불러왔는데, 내가 경험했던 첫 프로젝트가 떠올랐다. 국비학원에서 연식 있으신 강사님에게 배우며 프로젝트를 진행했는데, 스프링부트가 아닌 스프링으로 프로젝트를 해 보라는 말씀을 곧이곧대로 듣고 당시 maven으로 팀원과 손수 하나하나 환경 설정을 했다. 각자의 로컬환경에서 프로젝트를 통일하는데도 어려움이 꽤 있었다. 빌드 속도도 빠르고 복잡한 pom.xml로부터 해방시켜 주는 Gradle... 앞으로는 Gradle 쓸 일만 있었으면 싶은 바람이 있지만 두 빌드툴을 다 사용해 보는 경험은 나름대로 유의미할 거라고 생각해 본다. 섹션1생애 최초 API 만들기2-4강에서 서버 요청, 네트워크, HTTP와 API의 기초적인 개념을 학습하였다. 비유를 활용한 강사님의 설명이 굉장히 이해하기 쉽고 재미있었다. 대략 알고 있는 내용도 많았으나 복잡한 용어로 곧장 설명하고자 하면 머리에서 정리되지 않았던 것이 비유적으로, 또 원인 중심적으로 접근하니 훨씬 쉽고 간단명료하게 와닿는다. 특히 [집 주소]는 [ip] , 이를 알기 쉽게 [파란집]으로 대체한 것이 [도메인] 처럼 실생활적 단어에 일대일로 대응하여 용어를 설명하는 방식이 빠른 이해에 효과적이었다.HTTP Method도 이미 배우고 프로젝트로 구현해본 개념이지만 이 강의를 들으며 이제야 내가 무엇을 하고 있었는지가 확실해진 기분이 든다. 한 편으로는 내 머릿속이 이리도 엉망진창이었구나 싶다. 내가 무엇을 하는지 알고 행하는 것과 모르고 행하는 것은 정말 다르다. 아무래도 다 알기 전에 실천하고 행하는 것이 개발 공부의 미덕으로 여겨지고는 하는데, 나 자신은 개인적으로 선이해가 수행되지 않으면 실행하는 과정을 굉장히 힘겨워하는 타입이다. 지난 프로젝트 경험은 일단 하나하나 부딪히는 방식이었기에 여전히 머릿속에서 정리되지 않은 개념이 많다. 이번 강의 스터디가 모르고 행했던 것들을 다시 한 번 이해하는데 많이 도움되고 있고, 앞으로도 그럴 것이 기대된다. 차 주의 학습 목표이번 주 학습 시간이 적었던 것이 아쉽고, 다음 주부터는 진도표에 맞출 수 있도록 이른 시일 내에 진도율을 높이는 것을 목표로 더 적극적으로 수강할 것이다.  미션 과정 및 회고1일차 미션 - @Annotation어노테이션을 사용하고 있었지만 어노테이션의 의미에 대해 따로 디깅해 본 적은 없었기에 확실한 개념 이해에 도움을 주는 미션이었다. 구글링을 통해 여러 블로그를 찾아보고 책도 들춰보고 GPT에도 물어본 결과를 취합하여 질문에 따른 답을 작성했다. 내가 사용해 본 것들 외에도 컴파일 시에 검사를 하게하는 등 많은 기능을 하는 다양한 어노테이션들과, 커스텀 어노테이션을 정의하는 방법에 대해 새롭게 알게 되었다.https://dev-de.tistory.com/76 2일차 미션 - api 만들기2일차 미션으로는 GET, POST API를 만드는 세 가지 문제를 해결하였다. 어떤 방법이 더 나을지 나름대로 고민하였으나 완전히 만족스럽지는 않다. 또한 PostMan의 편의성에 감탄했다. 기초가 부족한 편이기에 아무것도 없었다면 List로 JSON을 받는다는 생각을 못 했을 텐데 문제에 Hint가 있는 것이 도움 되었다. 강사님의 피드백에 따라 date를 String으로 받지 않고 LocalDate를 바로 사용하는 방식으로 수정할 것이다.https://dev-de.tistory.com/77 3일차 미션 - 람다식에 대해람다식에 대해서는 이전에 타인의 코딩테스트 답변을 보고 공부 필요성을 느껴 간단히 알아본 적이 있었기에 그때 작성한 블로그 글을 보고 질문에 답변했다. 그러나 미션과 함께 제시된 [키워드]에 맞추어 디깅하다보니 람다식과 관련하여 여전히 잘 모르고 있던 내용들이 쏟아졌고 훨씬 깊이 있게 공부할 수 있었다.https://dev-de.tistory.com/78  소감 및 각오아직 많이 진행하지 않았지만 벌써 이번 인프런 워밍업 클럽 1기 스터디와 <자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]> 강의를 통해 새롭게 알고 배운 것이 많다. 지식적인 면 외에도 처음 인프런 워밍업 클럽 신청 시에 적어서 제출했던 '이번 스터디를 통해 기대하는 바'가 이루어지고 있다. 일상 유지를 어려워하며 취준을 위한 노력이 멈췄던 내게 정말로 다시 발을 내딛는 계기가 되어준다. 끝까지 강의와 미션 수행을 잘 따라가며 이 작은 레이스를 탈 없이 완주하고, 많은 것을 얻어가고 싶다.  

백엔드인프런워밍업클럽

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

01_네트워크와 API☾ Network데이터를 주고 받는 것(=택배)☾ IP각 컴퓨터의 고유 주소(=집 주소)256를 넘지 않는 4개의 숫자로 이루어짐ex. 대한시 민국구 서울동☾ Domain NameIP는 외우기 어려우니까 외우기 쉽게 별칭을 달아준 것ex. 빨간집☾ port number컴퓨터에서 돌아가는 여러 프로그램 중 한 프로그램을 특정하는 것ex. 홍길동☾ HTTP컴퓨터 간의 데이터를 주고 받는 표준(=운송장)ex. 내놓아라 파란집 둘째, 빨간포션 2개HTTP 요청GET /portion?color=red&count=2 Host: spring.com:3000 HTTP method(GET) : HTTP 요청을 받는 컴퓨터에게 요구하는 행위(데이터를 달라)path(/portion) : HTTP 요청을 받는 컴퓨터에게 원하는 자원Query(?color=red&count=2) : 자원을 요구할 때 필요한 조건Host : HTTP 요청을 받는 컴퓨터와 프로그램 정보POST /oak/leather Host: spring.com:3000 오크가죽정보 HTTP method(POST) : HTTP 요청을 받는 컴퓨터에게 요구하는 행위(데이터 저장해라)path(/oak/leather) : HTTP 요청을 받는 컴퓨터에게 원하는 자원Body(오크가죽정보) : 실제 저장할 정보Host : HTTP 요청을 받는 컴퓨터와 프로그램 정보정보를 보내는 2가지 방법Query : GET, DELETE에서 사용body : POST, PUT에서 사용HTTP 응답HTTP/1.1 200 OK Content-Type: application/json { "name":"A", "age":null } <aside> 💡 첫째줄 - 상태코드 여러줄 - 헤더 (한 줄 띄기) 여러줄 - 바디</aside>상태코드200 OK : 정상적으로 수행300 Moved Permanently : 다른 곳으로 옮겨가라404 Not Found : 요청을 찾을 수 없다500 Internal Server Error : 내부에 문제가 생김☾ API(Application Programming Interface)정해진 약속을 하여 특정 기능을 수행하는 것<aside> 💡 첫째줄 - Method path Query여러줄 - 헤더(여러 줄 가능)(한 줄 띄기)여러줄 - 바디(여러 줄 가능)</aside>☾ URL(Uniform Resource Locator)<http://spring.com:3000/portion?color=red&count=2> 주소창http : 사용하고 있는 프로토콜spring.com:3000 : 도메인 이름. 포트, 도메인 이름은 IP로 대체 가능portion : pathcolor=red&count=2 : 쿼리. 추가 정보02_GET APIQuery를 사용하여 데이터 요청☾ 덧셈 API 명세서HTTP Method HTTP Path Query(key, value) API의 반환 결과 GET /add int number1, int number2 int - 두 숫자의 덧셈 결과☾ @RequestParamcontroller/calculator/CalculatorControllerpackage com.group.libraryapp.controller.calculator; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; // @RestController : 주어진 클래스를 Controller(API의 진입 지점)으로 만들어 준다. API를 개발하려고 하는 클래스에 작성. 이 어노테이션이 있어야 클래스 안에 함수를 만들고 API 호출됐을 때 이 함수로 연결 @RestController public class CalculatorController { // @GetMapping("/add") : GET /add. 아래 함수를 HTTP Method가 GET이고 HTTP path가 /add인 API로 지정한다. @GetMapping("/add") public int addTwoNumbers(@RequestParam int number1, @RequestParam int number2) { // @RequestParam : Query를 통해서 넘어온 데이터를 함수 파라미터에 넣을 때 사용 return number1 + number2; } } @RequestParam 문제점 : Query가 늘어나면 함수의 파라미터도 길어짐☾ DTO해결책 : 객체를 받아서 사용dto/calculator/request/CalculatorAddRequestpackage com.group.libraryapp.dto.calculator.request; public class CalculatorAddRequest { private final int number1; private final int number2; public CalculatorAddRequest(int number1, int number2) { this.number1 = number1; this.number2 = number2; } public int getNumber1() { return number1; } public int getNumber2() { return number2; } } controller/calculator/CalculatorControllerpackage com.group.libraryapp.controller.calculator; import com.group.libraryapp.dto.calculator.request.CalculatorAddRequest; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; // @RestController : 주어진 클래스를 Controller(API의 진입 지점)으로 만들어 준다. API를 개발하려고 하는 클래스에 작성. 이 어노테이션이 있어야 클래스 안에 함수를 만들고 API 호출됐을 때 이 함수로 연결 @RestController public class CalculatorController { // @GetMapping("/add") : GET /add. 아래 함수를 HTTP Method가 GET이고 HTTP path가 /add인 API로 지정한다. @GetMapping("/add") public int addTwoNumbers(CalculatorAddRequest request) { // API 호출될 때 주어진 Query가 이 객체에 있는 값에 들어가게 됨 return request.getNumber1() + request.getNumber2(); } }  DTO(Data Transfer Object) : 정보를 전달하는 역할의 객체03_POST APIHTTP body를 사용하여 데이터 받음JSON(JavaScript Object Notation)객체 표기법HTTP body에서 사용됨{ "key": value } ☾ 곱셈 API 명세서HTTP Method HTTP Path HTTP Body API의 반환 결과 POST /multiply { “number1”:숫자, “number2”:숫자 } 숫자(곱셈 결과)☾ 코드로 구현dto/calculator/request/CalculatorMultiplyRequestpackage com.group.libraryapp.dto.calculator.request; public class CalculatorMultiplyRequest { private int number1; private int number2; public int getNumber1() { return number1; } public int getNumber2() { return number2; } } controller/calculator/CalculatorControllerpackage com.group.libraryapp.controller.calculator; import com.group.libraryapp.dto.calculator.request.CalculatorAddRequest; import com.group.libraryapp.dto.calculator.request.CalculatorMultiplyRequest; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; // @RestController : 주어진 클래스를 Controller(API의 진입 지점)으로 만들어 준다. API를 개발하려고 하는 클래스에 작성. 이 어노테이션이 있어야 클래스 안에 함수를 만들고 API 호출됐을 때 이 함수로 연결 @RestController public class CalculatorController { @PostMapping("/multiply") // POST /multiply public int multiplyTwoNumbers(@RequestBody CalculatorMultiplyRequest request) { // @RequestBody : POST API에서 HTTP body 안에 담긴 json을 DTO 객체로 변환시킬 수 있음. DTO 객체 앞에 작성. return request.getNumber1() *request.getNumber2(); } }  04_유저 생성 API☾ 도서관 사용자 등록 API 명세서HTTP Method HTTP Path HTTP Body(JSON) 결과 반환 POST /user { “name”: String(null 불가능), “age”: Integer } x (HTTP 상태코드 200 OK면 충분)☾ POST API 구현dto/user/request/UserCreateRequestpackage com.group.libraryapp.dto.user.request; public class UserCreateRequest { private String name; private Integer age; public String getName() { return name; } public Integer getAge() { return age; } } domain/user/Userpackage com.group.libraryapp.domain.user; // saveUser API가 사용돼서 유저가 저장되면 이 객체를 만들어서 실제 리스트에 저장 public class User { private String name; private Integer age; public User(String name, Integer age) { // API 통해서 들어온 name 값이 null이거나 비어있을 경우 예외 던짐 if (name == null || name.isBlank()) { throw new IllegalArgumentException(String.format("잘못된 name이 들어왔습니다.", name)); } this.name = name; this.age = age; } } controller/user/UserControllerpackage com.group.libraryapp.controller.user; import com.group.libraryapp.domain.user.User; import com.group.libraryapp.dto.user.request.UserCreateRequest; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import java.util.ArrayList; import java.util.List; @RestController public class UserController { // Instance 생성 private final List<User> users = new ArrayList<>(); @PostMapping("/user") // 1. POST /user가 실행되면 public void saveUser(@RequestBody UserCreateRequest request) { // 2. 함수 실행. json 형식으로 HTTP Body에 name과 age가 들어오면 DTO로 값이 매핑 users.add(new User(request.getName(), request.getAge())); // 3. 유저 생성. 만들어진 유저 객체는 Users 리스트에 저장된다. } // 4. 200 OK 반환 } 05_유저 조회 API☾ 유저 조회 API 명세서HTTP Method HTTP Path Query 결과 반환 GET /user 없음 { “id”: Long, “name”: String(null 불가능), “age”: Integer }Id : 유저 별로 겹치지 않는 유일한 번호(Primary Key). 여기서는 저장할 때 List에 담겨 있는 유저의 순서를 id로 지정Controller에서 getter가 있는 객체를 반환하면 JSON이 된다.package com.group.libraryapp.domain.user; public class Fruit { private String name; private int price; public Fruit(String name, int price) { this.name = name; this.price = price; } public String getName() { return name; } public int getPrice() { return price; } } package com.group.libraryapp.controller.user; import com.group.libraryapp.domain.user.Fruit; import com.group.libraryapp.domain.user.User; import com.group.libraryapp.dto.user.request.UserCreateRequest; import com.group.libraryapp.dto.user.response.UserResponse; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import java.util.ArrayList; import java.util.List; @RestController public class UserController { @GetMapping("/fruit") public Fruit fruit() { return new Fruit("바나나", 2000); } }  JSON 형식으로 반환☾ GET API 구현domain/user/Userpackage com.group.libraryapp.domain.user; // saveUser API가 사용돼서 유저가 저장되면 이 객체를 만들어서 실제 리스트에 저장 public class User { private String name; private Integer age; public User(String name, Integer age) { // API 통해서 들어온 name 값이 null이거나 비어있을 경우 예외 던짐 if (name == null || name.isBlank()) { throw new IllegalArgumentException(String.format("잘못된 name이 들어왔습니다.", name)); } this.name = name; this.age = age; } public String getName() { return name; } public Integer getAge() { return age; } } dto/user/response/UserResponsepackage com.group.libraryapp.dto.user.response; import com.group.libraryapp.domain.user.User; public class UserResponse { private long id; private String name; private Integer age; public UserResponse(long id, User user) { this.id = id; this.name = user.getName(); this.age = user.getAge(); } public long getId() { return id; } public String getName() { return name; } public Integer getAge() { return age; } } controller/user/UserControllerpackage com.group.libraryapp.controller.user; import com.group.libraryapp.domain.user.Fruit; import com.group.libraryapp.domain.user.User; import com.group.libraryapp.dto.user.request.UserCreateRequest; import com.group.libraryapp.dto.user.response.UserResponse; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import java.util.ArrayList; import java.util.List; @RestController public class UserController { // Instance 생성 private final List<User> users = new ArrayList<>(); @PostMapping("/user") // 1. POST /user가 실행되면 public void saveUser(@RequestBody UserCreateRequest request) { // 2. 함수 실행. json 형식으로 HTTP Body에 name과 age가 들어오면 DTO로 값이 매핑 users.add(new User(request.getName(), request.getAge())); // 3. 유저 생성. 만들어진 유저 객체는 Users 리스트에 저장된다. } // 4. 200 OK 반환 @GetMapping("/user") public List<UserResponse> getUsers() { // UserResponse 반환 List<UserResponse> responses = new ArrayList<>(); // 빈 UserResponse 리스트 생성 for (int i = 0; i < users.size(); i++) { responses.add(new UserResponse(i + 1, users.get(i))); // 우리가 갖고 있는 List<User> users를 userResponse로 변환 } return responses; } } 현재 API의 문제점서버 재시작하면 데이터 사라짐유저 정보가 메모리에서만 유지되고 있기 때문  일주일 간의 학습 내용에 대한 간단한 회고를 작성해 주세요.API 제작을 어느 정도 알고 있다고 생각했는데 직접 해보니 아직 부족하다는 생각이 들었다. 복습 시간을 더 가져야겠다고 생각했다. 초반부에는 내용 정리를 꾸준히 하다가 점차 미루게 됐다. 주말에 남은 내용을 정리하고 다음주부터는 다시 일정에 맞게 내용 정리를 해야겠다.  미션을 해결하는 과정을 요약해 주세요.강의에서 작성한 코드와 주석을 읽으면서 내용을 복습하고, 이를 바탕으로 미션을 해결했다.다른 사람이 작성한 코드도 함께 읽어보며 미션을 했다.  미션 해결에 대한 간단한 회고를 작성해 주세요.API 만드는 미션이 생각보다 쉽지 않았다. 우선 제출은 했지만 추후에 수정할 필요가 있을 것 같다.

장종원

[인프런 워밍업 클럽 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가 사용하게끔 만들어줄 수 있음@GetMappingapi의 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-ddtime : 시간, HH:mm:ssdatetime : 날짜와 시간을 합친 타입, yyyy-MM-dd HH:mm:ss위의 SQL이 DDL(Data Definition Language)아래는 DML(Data Manipulation Language)조회 Queryselect * 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 ('사과', '수박');업데이트 Queryupdate fruit set price = 1500 where name = '사과';where 조건을 주지 않고 실행할 수 있으나, 모든 경우를 모두 변경할 수 있으니 조심해야 함삭제 Querydelete 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/DELETEjdbcTemplate.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 해제참고 : https://blog.naver.com/kkson50/221251167091@RequestBody에 매핑되는 DTO는 왜 빈 생성자가 필요한가참고 : https://innu3368.tistory.com/181 과제1. 어노테이션을 사용하는 이유(효과)는 무엇일까?https://slime-feels-660.notion.site/acb06609050b490a8d1de99c6395e8dd?pvs=4지금까지 어노테이션들을 너무 자연스럽게 쓰다보니 왜 쓰는지나 개념적인 부분을 생각하지 않고 너무 편해서 기능만 알고 쓴 것 같았는데 조사하다보니 단순 어노테이션이라는 키워드 하나에도 공부할 수 있는 부분이 상당히 많고 깊었다.앞으로도 단순히 사용법만 알고 기능을 사용하기보다 왜? 라는 것에 초점을 맞춰 공부해야 한다는 생각이 들었다.과제2. API 만들기https://slime-feels-660.notion.site/14c2b5efc21c46cd9ec46124704b31ea?pvs=42-1, 2-2 과제를 할 때는 생각보다 금방 했는데, 2-3번 과제를 할 때 다 만들어놓고 해결되지 않는 것을 이해를 못했다.구글링을 통해 결국 이유를 찾았지만 쉽다 생각한 것에도 또 무언가 있었다. 얕게 공부하기보다 깊게 공부할 수 있도록 해야겠다는 마음을 다시 먹게 만들어 준 과제같았다. 과제3. 자바의 람다식은 왜 등장했을까? 람다식과 익명 클래스는 어떤 관계가 있을까? 람다식의 문법은 어떻게 될까?https://slime-feels-660.notion.site/742bd212b32e4830b6fea014dc70c443?pvs=4람다식을 사실 많이 쓰진 않은 것 같다. 익숙한 걸 쓴다 해야할까 쓰면 코드량이 줄고 여러 기능들이 추가되지만 자연스럽게 코딩을 하다보면 편한 방법을 쓰게 된다. 추가적으로 스터디를 해서 내 익숙한 코딩방법을 좋은 방법으로 교정하는 작업이 필요하겠다는 생각을 하게했다.마무리1주를 돌아보며 생각보다 시간이 부족하다. 발자국을 위해, 복습을 위해 내용을 노션에 적으면서 수강을 하니 이 정도 시간이 들겠지 하고 계획한 것보다 시간을 더 쓰게 됐었다. 시간이 있는 날은 여유가 있네 생각하고 바로 쉬는 것보다 조금 더 예습을 해두는 게 공부하기로 계획한 것을 밀리지 않고 계속 해낼 수 있을 것 같아 그렇게 해보려 한다.아, 그리고 실수로 5/3 특강을 날짜를 착각해서 시간을 놓치게 되었는데 너무 아쉽고 17일날에는 꼭 알람을 해놓고 들어야겠다.공부를 하며, 강의를 들으며 더 깊게 공부하고 싶은 것들이 종종 보였는데, 그런 것들도 키워드를 모아 시간을 내 공부하여 궁금한 것들을 채워나가야겠다. 

백엔드백엔드워밍업클럽발자국

김동현

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

Section 1 - 생애 최초 API 만들기 Java를 공부하기 전에 알아두면 좋을 것들 #1 #2JVM: 자바 가상 머신, 컴파일된 코드를 읽고 실행JDK: JVM을 포함해 자바 컴파일러(javac), 자바 실행 도구, 라이브러리 등 다양한 개발 도구 제공 HTTP, APIHTTP(Hypertext Transfer Protocol): 웹 브라우저가 웹 페이지를 요청하고 서버가 그에 대한 응답을 주는 기본적인 통신 규약API(Application Programming Interface): 소프트웨어 간의 상호작용을 위한 인터페이스를 제공정리컴퓨터간의 통신은 HTTP라는 표준화된 방식HTTP 요청은 HTTP Method (GET, POST)와 Path (/portion) 가 핵심요청에서 데이터를 전달하기 위한 2가지 방법은 쿼리와 바디HTTP 응답은 상태 코드가 핵심클라이언트와 서버는 HTTP를 주고 받으며 기능을 동작하는데 이때 정해진 규칙을 APIGET API, POST APIGET API는 쿼리로, POST API는 바디에 담아 보냄.(무조건은아님)DTO를 만들어서 구현가능 이경우 @RequestParam 제거 !과제 2일차 Section 2 - 생애 최초 Database 조작하기DBDB 없이 만들면 메모리에만 저장됨 => 데이터가 다날아감DB => 데이터를 구조화 시켜 저장 MySQL 연동application.yml 만들기JdbcTemplate 사용직접 sql을 연동하지 않고 JPA만 사용했던 경험이 있다.sql 쿼리를 직접 사용해서 db에 접근가능함도 알음  Section 3 - 역할 분리 클린코드코드만 보고 의미 파악할 수 있게 함함수는 최대한 작게 만들고 한 가지 일만 수행클래스는 작아야 하고 하나의 책임만 가져야 함유지보수도 좋음Controller 3단 분리Controller 역할 - API의 진입 지점으로써 HTTP Body를 객체로 변환Service 역할 - 현재 유저가 있는지, 없는지 등을 확인하고 예외 처리(메인 로직 수행)Repository 역할 - SQL을 사용해 실제 DB와의 통신을 담당Layered Architecture 1주차 회고스터디 시작전 모든 미션과 과제를 수행하고자 했는데 첫번째 과제부터 놓쳐버렸다... 남은 것들은 꼭 다하겠다.오랜만에 스프링을 다시 하는데 당시에 바로 jpa를 바로 사용해서 db랑 연동을 했었는데 쿼리로 연동하는 것도 알게 되었음. 기초가 중요하다.Java에 아직 덜 익숙함도 느꼈음. Java 다형성 부분에 대해서 다시 복습해야겠다.남은 스터디 기간에도 집중해서 꼭 많은 것을 얻어가는 시간이 되어야겠다.

백엔드워밍업백엔드스터디

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

1주차 첫 번째 발자국 이번 주차에는 RESTful api 를 spring 에서 어떻게 사용하는지에 대해 중점적으로 배웠다. 수업내용을 위주로 정리해보자면. URL 및 api 표준데이터를 주고받는 표준 HTTP e.g)GET /portion?color=red&count=2 HOST:spring.com:3000 GET (HTTP Method) HTTP 를 요청하는 행위 Host:spring.com:3000 HTTP 요청을 받는 컴퓨터와 프로그램 정보 /portion => path 요청 자원 color=red&count 자원의 세부조건 & 추가조건 GET: 데이터를 달라, 쿼리 POST: 데이터를 저장하라, 바디 PUT: 데이터를 수정하라, 바디 DELETE: 데이터를 삭제하라, 쿼리  이 때 위와같이 서버와 클라이언트가 정한 규칙을 API 라고 한다.  Springanotaition@RestController 주어진 Class를 Controller 로 등록한다. Controller : API 입구 @GeMapping("/add"): 아래 함수를 HTTP Method 가 Get이고 HTTP path 가 /add 인 API 로 지정한다. @RequestParam 같은 이름을 가진 쿼리의 값이 들어온다 대문자 String, Integer => Null 표현 가능DB RDS => 데이터를 표처럼 구조화시켜 저장함 / MySql SQL => 표처럼 구조화된 데이터를 조회하는 언어 회고록이번 SQL 관련 restful 강의를 들으면서 느낀 점은,현재 실무에서는 ORM 혹은 SP 를 사용하면서 CRUD 행위를 하고 있다. 이 때 강의를 보면서 실제로 sql 날 것으로 적으면서 왜 ORM 을 사용하고, 자체적인 프레임워크가 존재하는지 다시 한번 깨달았고, sql injection 이라던지실제 업무 환경 혹은 코어쪽에서는 신경 쓸 부분이 엄청 많아보였다.   

미플

[인프런 워밍업 스터디 클럽] 1기 - 첫 번째 발자국

자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]1주차이 끝이 났다. 고민을 많이 하고 시작한 스터디였는데 무엇을 알고, 모르는지 확인함에 도움을 받고 있다. 무엇을 배웠나?강의는 교과서 같았다. 각 강의와 섹션마다 학습목표와 정리가 이뤄진다. 반복되는 과정을 통해 점진적으로 문제가 해결되는 과정을 배웠다. 서버개발자가 되기 위한 최소한의 이론을 다루고 실습을 먼저 시작했다. 간단한 기능으로 시작했던 애플리케이션에 요구사항이 추가되고 어떻게 계층화 아키텍처로 나눌 수 있을지 이야기하는 시간을 가졌다. 1일 차: 서버 개발을 위한 환경 설정 및 네트워크 기초스프링 프로젝트를 시작하는 방법어떻게 새로운 프로젝트를 시작할까?기존에 운영 중인 프로젝트에 투입 됐을 때 어떻게 시작할 수 있을까? 서버 개발자가 되기 위해 알아야 하는 기본적인 지식네트워크, IP, 도메인, 포트, HTTP 요청과 응답, 클라이언트 - 서버, API란 무엇인가  과제: 자바 어노테이션무의식 중에 많이 사용했지만 궁금해하지 않았다. 이전에는 어떻게 문제를 해결했는지 알 수 있었다. 2일 차: 첫 HTTP API 개발Spring Boot를 사용해 API 만들기 GET, POST웹 개발에 기본이되는 HTTP를 다룬다.GET은 쿼리를 사용해 조회에 사용되고, POST는 body를 사용해 생성에 주로 사용된다.   과제: API 실습 1, 2일 차를 제대로 이해하고 있는지 점검을 했다. 문제를 해결하는 데 시간이 오래 걸리지 않았지만 정리하는데 오랜 시간이 걸렸다.3일 차: 기본적인 데이터베이스 사용법디스크와 메모리의 차이, 데이터베이스(Database)는 왜 필요한가?SQL 사용, MySQL 다루기이전에 만들었던 기능들은 서버가 종료되면 데이터가 모두 사라졌다. 데이터를 계속 저장하기 위해서 데이터베이스를 사용하자.테이블 생성, 데이터 추가, 조회, 수정, 삭제 과제: 익명 클래스와 람다 4일 차: 데이터베이스를 사용해 만드는 API스프링 서버와 연결하여 데이터베이스 다루기, API 예외상황 다루기, 예외처리PUT, DELETE를 학습하고 수정데이터베이스와 통신해서 조회되는 데이터가 없으면 어떻게 에러를 반환할지 배운다.  5일 차: 클린코드의 개념과 첫 리팩터링좋은 코드는 왜 중요한가? 계층화 아키텍처(Layered Architecture)의 등장, 리팩터링Controller에 역할을 덜어주기 위해 리팩터링을 진행했다.역할을 나누고 왜 좋은 코드의 개념에 대해 배웠다. 마무리스터디 시작 전에 강의를 듣고 정리해 둬서 다행이다. 주말을 앞두고 몸도 마음도 지쳐서 과제를 제출하지 못할 뻔했다. 문제가 발생했던 이유는 전 날 푹 잠들지 못해서 발생했다. 단거리가 아니라 장거리 달리기라 생각하고 컨디션 관리에 더욱 신경 써야겠다. 다음 주도 미루지 않고 마무리했으면 좋겠다.

백엔드인프런워밍업클럽

최강현

[인프런 워밍업 클럽 스터디 1기] BE 1주차 발자국

강의 수강,과제 수행하면서 생겼던 궁금증을 해결하는 과정을 위주로 블로그 글을 작성하려고 합니다. 강의 수강 1일차 - OT 인프런 워밍업 클럽 스터디 및 일정 소개 코치님과 구글 밋을 통해 온라인 OT를 진행하였습니다.간단한 스터디 과정 및 일정에 대해 소개 해줬고, 코치님이 이거까지 알아야하나? 라는 주제로 의견을 공유해주셨습니다. 2일차 - 서버 개발을 위한 환경 설정 및 네트워크 기초 (1강 ~ 5강)2일차에는 서버, 네트워크, HTTP, API를 배웠다.API가 무엇인지 잘 몰랐는데 Input을 주면 OutPut이 나오는 함수와 비슷하다는걸 알게 되었다. API가 무엇인지 와닿지 않았는데 감을 잡을 수 있었다3일차 - 첫 HTTP API 개발 (6강 ~ 10강)GET API와 POST API를 개발해봤다.GET 요청은 쿼리를 통해서 요청을 주고 POST 요청은 body를 통해 요청을 주는데@RequestParam을 통해 주어지는 쿼리를 함수 파라미터에 넣는다.파라미터 대신에 DTO 객체를 넣어서 쿼리를 받을 수 있다public class CalculatorAddRequest{ private final int number1; private final int number2; public CalculatorAddRequest(int number1, int number2) { this.number1 = number1; this.number2 = number2; } public int getNumber1() { return number1; } public int getNumber2() { return number2; } }  post 요청은 body로 들어오는 JSON을 DTO로 바꿔주기 위해 @RequestBody를 사용해야하는데@RequestBody를 사용하면 DTO 객체에 생성자를 만들지 않아도 괜찮은데 이 이유가 궁금했다public class CalculatorMultiplyRequest { private int number1; private int number2; public int getNUmber1(){ return number1 } public int getNumber2(){ return number2; } }다음과 같은 이유를 찾을 수 있었다.Spring의 동작 방식: @RequestBody 어노테이션이 적용된 메서드 파라미터에는 HTTP 요청의 본문을 기반으로 객체가 생성됩니다. Spring은 이를 위해 클래스의 기본 생성자를 호출하여 빈 객체를 생성하고, 요청의 본문에서 추출한 데이터를 객체에 설정합니다.4일차 - 기본적인 데이터베이스 사용법 (11강 ~ 13강) MySQL의 사용법을 배웠다DDL(데이터 정의어) - CREATE, ALTER, DROPDML(데이터 조작어) - INSERT, UPDATE, SELECT, DELETE이 2개를 사용해서 데이터를 DB에 생성, 조회, 갱신, 삭제하고5일차 - 데이터베이스를 사용해 만드는 API (14강 ~ 16강)이 강의를 통해 사람이 직접 DB에 접속해서 DB를 조작하는게 아닌 Spring 서버가 MySQL DB에 접근해서 DB를 조작하게 API를 만들었다. 6일차 - 클린코드의 개념과 첫 리팩토링(17강~ 18강) 이 강의를 통해 저번 강의를 통해 만든 컨트롤러 클래스를 3개의 클래스로 쪼개 보았다.Controller 클래스 - API의 진입 지점으로써 HTTP Body를 객체로 변환Service 클래스 - 분기처리 로직Repository 클래스 - SQL을 사용해 실제 DB와의 통신을 담당 컨트롤러 클래스 작성 시 JdbcTemplate 객체를 생성하는데 new 키워드를 사용하지 않고 생성했다이게 어떻게 가능한지 궁금해서 찾아보니스프링에서는 보통 dependency injection을 사용하여 객체를 주입합니다. 이 코드에서도 JdbcTemplate jdbcTemplate는 생성자를 통해 주입됩니다.생성자 public UserController(JdbcTemplate jdbcTemplate)에서 JdbcTemplate 객체가 주입됩니다. Spring이 UserController를 생성할 때, 필요한 JdbcTemplate 객체를 찾아서 자동으로 주입해줍니다. 이것이 Spring의 IoC (Inversion of Control) 컨셉입니다.따라서 new 키워드를 사용하여 직접 객체를 생성할 필요가 없고, Spring이 해당 객체를 관리하고 주입해줍니다.미션1일차어노테이션을 미리 정의 해두면 @RequestParam 같은 한 단어만 작성해주면 스프링이 알아서 GET 요청의 쿼리를 메서드의 파라미터로 바꿔준다.어노테이션은 이런 마법 같은 일을 해준다.  2일차문제1Controller에서 getter 메서드가 있는 객체를 반환하면 반환 값이 JSON으로 반환 한다! CalculatorResponse.java public class CalculatorResponse { private int add; private int minus; private int multiply; public CalculatorResponse(int num1, int num2) { this.add = num1 + num2; this.minus = num1 - num2; this.multiply = num1 * num2; } public int getAdd() { return add; } public int getMinus() { return minus; } public int getMultiply() { return multiply; } }  ExController.java@RestController public class ExController { @GetMapping("/api/v1/calc") public CalculatorResponse plusMinusMultiplyCalculator(@RequestParam int num1, int num2) { return new CalculatorResponse(num1, num2); } } Response문제2ExController.java@RestController public class ExController { @GetMapping("/api/v1/day-of-the-week") public DateResponse dayOfTheWeek(@RequestParam String date) { return new DateResponse(date); } } DataResponse.java public class DateResponse { private Enum<DayOfWeek> dayOfTheWeek; public DateResponse(String date) { LocalDate parsed = LocalDate.parse(date); this.dayOfTheWeek = parsed.getDayOfWeek(); } public Enum<DayOfWeek> getDayOfTheWeek() { return dayOfTheWeek; } }  GET 메서드에서 파라미터의 value의 타입은 문자열로 들어오므로 DateResponse의 생성자에서 LocalDate.parse()를 통해 문자열을 LocalDate로 바꿔주었다. 문제3 ExController.java@RestController public class ExController { @PostMapping("/api/v1/multi-number-sum") public int multiNumberSum(@RequestBody CalculatorMultiNumber request) { int[] numbers = request.getNumbers(); int sum = Arrays.stream(numbers).sum(); return sum; } } CalculatorMultiNumber.javapublic class CalculatorMultiNumber { int[] numbers = new int[5]; public int[] getNumbers() { return numbers; } } ResponseResponse크기가 5개인 배열을 선언 하고 body에 길이가 6개를 리스트 넣고 요청해도 6개의 값을 반환한 값을 돌려준다.왜 그런지 이유를 찾고 싶었는데 못찾았다 ㅠㅠ 3일차람다식은 익명 클래스를 좀 더 쉽게 쓸 수 있게 자바8부터 도입된 개념이다. OOP인 자바는 람다식의 도입으로 함수형 프로그래밍도 가능해졌다하루에 몰아서 적으려니까 너무 힘들었다 다음주 회고록은 따로 초고를 그날 그날 적어놔야겠다..이 블로그에 올린 코드와 문제의 출처는 https://www.inflearn.com/course/%EC%9E%90%EB%B0%94-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-%EC%84%9C%EB%B2%84%EA%B0%9C%EB%B0%9C-%EC%98%AC%EC%9D%B8%EC%9B%90입니다  

백엔드java인프런워밍업클럽스프링spring자바

13blueberry

[인프런 워밍업 클럽 스터디] BE 스터디 1기 1주차 발자국

1주차 발자국 배웠던 것1주차에서는 기본적인 네트워크의 구성과 API, Database, 좋은 코드와 controller에 대해서 학습하였다. 좋았던 것 백엔드 스터디를 신청하게 된 이유는 간단하다. 서버 배포를 해보고 싶었기 때문이다. 본격적인 강의를 듣는 것은 처음인데, 큰 구조를 먼저 따로 공부하지 않고 필요한 것부터 배워도 강의 구성을 워낙 잘 해주셔서 나무만 보는 것이 아니라 큰 숲부터 볼 수 있어서 좋았다.  간단한 프로젝트를 위해 과거에 장고 프레임워크를 벼락치기한 경험이 있었고, 그때 간단하게 당장은 이렇다 하고 넘어간 통신 부분에 대해 자세히 배울 수 있어서 좋았다. 확실히 혼자 벼락치기 하는 상황에서 영어를 만나다 보니 급한 마음이 영향을 주어서 결국 애매하게 아는 상태가 되거나, 이도 저도 아닌 상태로 프로젝트를 엉성하게 마무리 한 경험이 있었다. 하지만 비유를 통해 잘 설명해 주시니 그동안 애매하게 알게 되면서 가진 의문점 등을 모두 해결할 수 있었다.  힘들었던 것이 커리큘럼을 시작하려고 급하게 자바 벼락치기를 해서 그런가 아직 이해하는데 오랜 시간이 걸린다. 모르는 것은 검색해 가면서 진행하지만 스터디에 많은 시간 소요가 들어서 일정 측면에서 부담스러울 때가 있다. 개인적인 문제이기에 이를 극복해 나가려면 주말이나 공휴일을 활용하는 것이 중요해 보인다. 다행히 2주차에는 월요일 진도가 없어서, 복습의 기회로 삼으면 좋을 것 같다. 과제 1질문 1. 어노테이션을 사용하는 이유 (효과) 는 무엇일까?질문 2. 나만의 어노테이션을 어떻게 만들 수 있을까?어노테이션의 사용 이유의 핵심은 간소화에 따른 오류 최소화라 생각했다. 간결한 코드로 수동으로 오랜 시간을 소요할 수 있는 작업을 간단하게 만들어주고, 그 과정에서 오류까지도 잡아줄 수 있다. 또한 어노테이션의 특성 상 자바 프레임워크들은 특정 기능을 쉽게 구현할 수 있었다.나만의 어노테이션은 @interface키워드를 사용하여 정의할 수 있다.과제 2 API 명세를 통해 GET, POST API 만들기여러 블로그글과 gpt를 참고해서 구현해냈다. 확실히 스스로 하나의 예시를 만들어 내니까 이해가 더 잘 되었다. 코드 작성보다 아직 폴더 구조를 이해하는 것이 더 힘들었다. 여러 번 코드가 의미하는 바를 따라가며 구조 자체를 먼저 이해하려고 했던 기억이 남아 있다.과제 3질문 1. 자바의 람다식은 왜 등장했을까?질문 2. 람다식과 익명 클래스는 어떤 관계가 있을까?람다도 결국 코드 간결화를 위해 도입되었다. 또한 람다식은 익명 클래스를 더 간결하게 표현하는 방법이라 볼 수 있기에, 람다식 자체는 결국 익명 클래스다. 

백엔드인프런워밍업클럽백엔드스터디