프로젝트

NO RUN NO LIFE - 웹 프로젝트 과제 1주차

김동디 2026. 5. 11. 18:59

0.  첫 웹 프로젝트


  • 드디어 내가 웹 프로젝트를 만들게 되었다. 문자열 계산기 과제를 하던게 엊그제 같은데 내가 웹을 만든다고..?


    멘토님께서 프로젝트 과제 기간은 6주차로 설계 해주셨는데 내가 열심히만 한다면 2주안에도 끝낼 수 있다고 하셨다.
    과제는 주 기준으로 알려주시지만 내 목표는 늦어도 4주안에는 끝내는 것이다.


    그리고 매주 추가되는 프로젝트 과제를 회고식으로 작성해보겠다.
    솔직히 지금 심정은 아무것도 모르겠다..ㅋㅋ 뭐부터 해야하지..?


    멘토님이 나는 야생(모든 이론을 공부하고 시작하는게 아니라 모르는게 생기면 그때 공부하고 바로 적용)적으로 하는것을 추천하셨다.


    나도 이 방법이 나에게 맞다고 생각하고 원래 개발자란 그런것이라고 하심


    이런저런 생각을 많이 하고 싶지도 않고 과제를 어떤 순서로 시작할지는 머릿속에 감이온다. 그럼 시작해보겠습니다!


    🔥마음을 불태워라🔥


1.  What Project?


러닝과 복싱 기록을 남기는 웹 서비스를 6주에 걸쳐 처음부터 만들어보는 과제

  • 나는 이때까지 살면서 운동을 장기간 쉬어본적이 한번도 없다.


    그래서 멘토님께서 본인이 진짜 쓸 수 있는 서비스라 동기 부여 가능하고,
    러닝과 복싱이 속성이 달라서 객체 설계 연습에 좋으며,


    데이터 쌓이면 통계, 차트도 자연스럽게 붙일 수 있다는 장점으로 이 프로젝트 과제를 내주셨다.


프로젝트 이름

  • 프로젝트 이름을 고민해보다가 내가 좋아하는 복싱 브랜드 중 'NO BOXING NO LIFE' 라는 브랜드가 있다.


    나는 이름은 직관적이고 짧은 스타일을 좋아한다. 그래서 NBNL 브랜드 이름을 인용해서


    내 첫 프로젝트 이름은 'NO RUN NO LIFE' 로 결정했다!!


    RUN이라는 단어가 보통은 “달리다”라는 뜻이라 러닝 앱처럼 느껴질 수도 있지만, 단순히 운동의 의미만 담고 싶진 않았다.


    축구에서 스페인어 “Vamos”가 단순 번역 이상으로 “가보자”, “해보자” 같은 분위기를 담고 있는 것처럼, RUN도 계속 앞으로 나아가고 움직인다는 의미로 사용했다.


    또 개발에서는 run이 코드를 실행한다는 의미로 쓰이는데, 이런 점도 프로젝트를 만들면서 자연스럽게 연결됐다.


    그래서 단순히 러닝만 뜻하는 게 아니라, 운동 기록을 꾸준히 이어가는 과정과 계속 실행하고 성장해나가는 의미를 함께 담아서 “NO RUN NO LIFE”라는 이름을 정하게 됐다.


🚘  2.  1주차 구현사항


지금부턴 1주차 구현사항을 하면서 처음 공부하면서 이론, 사용한것들을 정리하면서 작성해보겠다.

목표: 컨트롤러로 화면을 띄우고, 폼으로 데이터를 받아서 메모리(List)에 저장해보기. DB는 아직 안 씁니다.

📚  2-1.  이론 정리


1.  스프링 빈(Bean)이란?

  • 스프링의 IoC(Inversion of Control) 컨테이너에 의해 관리되는 자바 객체를 의미합니다.


  • 1-1. 주요 특징 및 생명주기

    • 제어의 역전 (IoC) : 객체의 생성 및 관리 권한이 개발자로부터 스프링 컨테이너로 넘어갑니다.
    • 의존성 주입 (DI) : 빈들 사이의 의존 관계를 컨테이너가 설정 파일(Annotation, XML 등)을 바탕으로 자동으로 연결해 줍니다.
    • 싱글톤(Singleton) 스코프 : 기본적으로 스프링은 빈을 싱글톤으로 생성하여, 애플리케이션 내에서 해당 빈의 인스턴스를 단 하나만 생성하고 공유합니다.
    • 생명주기(Lifecycle) 콜백 : postConstruct, preDestroy 등을 통해 빈의 생성 직후나 소멸 직전에 특정 로직을 수행하도록 설정할 수 있습니다.
  • 1-2. 빈을 등록하는 방법


    현대적인 스프링 개발에서는 주로 어노테이션 기반 설정을 사용합니다.


    1. 컴포넌트 스캔 (Component Scan)
    • 클래스 선언부 위에 @Component 어노테이션(또는 이를 상속하는 @Service, @Repository, @Controller)을 붙여 컨테이너가 자동으로 스캔하여 빈으로 등록하게 합니다.
    1. 자바 설정 파일 (Java Configuration)
    • 설정 클래스(@Configuration) 내에서 메서드에 @Bean 어노테이션을 붙여 직접 빈을 정의합니다. 외부 라이브러리 객체처럼 클래스 소스 코드를 수정할 수 없는 경우 주로 사용합니다.
  • 1-3. 스프링 빈의 장점


  • 객체 관리의 효율성 : 싱글톤 패턴을 직접 구현할 필요 없이 컨테이너 레벨에서 효율적으로 메모리를 관리합니다.

  • 유연한 결합도 : 인터페이스를 기반으로 의존성을 주입받으므로, 구현체가 바뀌어도 클라이언트 코드를 수정할 필요가 없어 유지보수성이 뛰어납니다.

  • 관심사의 분리 : 비즈니스 로직 외의 설정 정보 등을 분리하여 관리할 수 있습니다.



2.  @Component, @Controller, @Service가 어떤 관계?

@Controller, @Service, @Repository는 모두 @Component 기반이며, Bean 등록 기능에 각 계층의 역할 의미를 추가한 어노테이션이다.



3.  의존성 주입(DI)이란? 생성자 주입 vs 필드 주입, 왜 생성자 주입이 권장될까?

의존성 주입(DI)이란?

  • 객체가 자신이 사용할 객체(의존성)를 직접 생성하지 않고, 외부(스프링 컨테이너)에서 주입받는 설계 패턴을 의미합니다.
  • 객체 지향 설계의 핵심 원칙 중 하나인 '제어의 역전(IoC)'을 실제로 구현하는 방법론입니다.
  • 이를 통해 객체 간 결합도를 낮추고 유지보수와 테스트를 쉽게 할 수 있다.

생성자 주입 vs 필드 주입, 왜 생성자 주입이 권장될까?

  • 생성자 주입은 객체 생성 시점에 필요한 의존성을 강제할 수 있고, final을 통해 불변성을 보장하며 테스트와 유지보수에 유리하기 때문에 권장된다.



4.  HTML, CSS, JS 개념 및 사용해보기

4-1.  HTML(HyperText Markup Language)

  • 역할 : 웹 페이지의 뼈대와 구조
  • HTML은 웹 페이지에 어떤 내용이 들어갈지 결정하는 마크업 언어입니다. 제목, 본문, 이미지, 버튼 등 각 요소의 위치와 의미를 정의합니다.
    • 특징: <tag> 형태의 태그를 사용하여 정보를 감쌉니다.
    • 비유: 건물의 설계도나 인간의 골격(뼈대)에 해당합니다.
    • 예시: <h1>은 큰 제목, <p>는 단락, <a>는 링크를 의미합니다.

4-2.  CSS(Cascading Style Sheets)

  • 역할: 웹 페이지의 디자인과 스타일
  • HTML로 만든 뼈대에 색상, 글꼴, 간격, 배치 등 시각적인 요소를 입히는 스타일 시트 언어입니다.
    • 특징: 특정 HTML 요소를 선택(Selector)하여 어떤 스타일을 적용할지 선언합니다.
    • 비유: 건물의 인테리어(도배, 조명)나 인간의 외모(피부, 옷)에 해당합니다.
    • 예시: color: blue;는 글자색을 파란색으로, margin: 20px;는 바깥 여백을 설정합니다.

4-3.  JavaScript (JS)

  • 역할: 웹 페이지의 동적인 기능과 상호작용
  • 사용자의 동작(클릭, 입력, 스크롤 등)에 반응하여 웹 페이지가 실시간으로 변하게 만드는 프로그래밍 언어입니다.
    • 특징: 변수, 조건문, 함수 등을 사용하여 데이터를 처리하고 브라우저를 제어합니다.
    • 비유: 건물의 전력/엘리베이터 시스템이나 인간의 근육과 신경계(동작)에 해당합니다.
    • 예시: 버튼을 눌렀을 때 팝업창이 뜨게 하거나, 서버에서 새로운 데이터를 가져와 화면을 갱신합니다.

5.  UI/UX란?

5-1.  UI(User Interface)

  • 사용자가 “눈으로 보고 직접 조작하는 화면”으로 제품이나 서비스와 상호작용하는 접점 그 자체를 의미합니다. 시각적인 요소와 기술적인 구성이 핵심입니다.
  • 주요 구성 요소 : 버튼, 아이콘, 폰트, 컬러 스키마, 레이아웃, 입력창, 메뉴 바 등.
  • 핵심 목표 : 심미성(Aesthetics)과 가독성, 그리고 사용자가 조작하기 쉬운 명확한 설계를 제공하는 것입니다.
  • 개발 단계 : 주로 디자인 툴(Figma, Sketch)을 활용하여 구체적인 화면을 설계하며, 프론트엔드 개발로 구현됩니다.

5-2.  UX(User Experience)

  • UX는 사용자가 제품이나 서비스를 이용하면서 느끼는 총체적인 경험과 반응을 의미합니다. 사용자의 심리, 행동 패턴, 만족도를 모두 포괄하는 광범위한 개념입니다.
  • 주요 구성 요소 : 사용성(Usability), 효율성, 접근성, 감정적 만족도, 가치 전달 등.
  • 핵심 목표 : 사용자가 겪는 문제를 해결하고(Problem Solving), 제품을 사용하는 과정에서 긍정적인 감정을 느끼며 목표를 쉽고 빠르게 달성하게 하는 것입니다.
  • 개발 단계 : 사용자 리서치, 페르소나 설정, 유저 저니 맵(User Journey Map), 와이어프레임 설계 등을 포함합니다.

🚗  2-2.  프로젝트 설계


1.  패키지 설계


❗️  3.  학습 포인트  ❗️


3-1.  사용자가 /workouts/new 폼에서 등록 버튼을 눌렀을 때, 요청이 어떤 순서로 처리돼요?

    1. 사용자 폼 입력
    1. 등록 버튼을 누르면 JS의 submitWorkout() 함수 실행
    1. 클라이언트 사이드 유효성 검증
    • 운동 시간이 1분 미만이거나 메모가 비어있으면 alert 후 중단
    1. Fetch API가 서버로 POST /api/workouts 요청
    • Body에 JSON 형태로 데이터 담아서 전송
    • Content-Type: application/json 헤더 포함
    1. Spring Boot 내부 톰캣이 HTTP 요청 받음
    1. DispatcherServlet이 요청 가로챔
    • Spring MVC의 핵심 프론트 컨트롤러로 모든 요청은 얘를 먼저 거침
    1. 매핑 찾기
    • @PostMapping("/workouts") 발견 후 createWorkout() 메서드 실행
    1. @RequestBody 바인딩
    • JSON 데이터 → Workout 객체 변환
    1. @Valid 유효성 검증
    • @NotNull, @Min, @NotBlank 검증 실행
    1. Service 호출
    1. Repository 호출, 저장 처리
    1. Controller가 저장된 Workout 객체를 JSON으로 반환
    1. 프론트 JS가 응답 받음
    1. 응답 성공 시 index.html로 페이지 이동
    1. index.html에서 GET /api/workouts 호출
    1. 브라우저에 최종 목록 화면 표시

3-2.  @GetMapping과 @PostMapping을 왜 나눠 써요?

  • @GetMapping은 서버의 데이터를 조회하거나 화면을 보여줄 때 쓰고, @PostMapping은 사용자가 입력한 데이터를 서버에 저장하거나 변경할 때 쓴다. 그래서 운동 목록을 보여줄 땐 GET을 쓰고, 운동 기록을 등록할 땐 POST를 사용
  • 설계 의도와 역할 (멱등성)
    가장 큰 차이는 해당 요청이 서버의 상태를 변경하는가에 있습니다.
    • @GetMapping (조회): 데이터를 단순히 가져올 때 사용합니다. 같은 요청을 여러 번 보내도 서버의 데이터 상태가 변하지 않으며, 결과도 항상 같습니다. 이를 멱등성(Idempotency)이라고 합니다.
    • @PostMapping (생성/변경): 데이터를 서버로 보내 새로운 자원을 생성하거나 상태를 바꿀 때 사용합니다. 요청을 보낼 때마다 새로운 데이터가 쌓이므로 멱등성이 보장되지 않습니다.

3-3.  @Controller와 @RestController의 차이는?

  • @Controller (전통적인 Spring MVC 컨트롤러)
    주로 사용자가 보는 화면(View)을 응답할 때 사용합니다.

    • 반환 값 : 주로 String을 반환하며, 이는 View Resolver에 의해 특정 HTML 파일(Thymeleaf, JSP 등)을 찾아 화면을 렌더링합니다.
    • 작동 방식 : 컨트롤러가 로직을 처리한 후, 지정된 이름의 뷰를 찾아 사용자에게 보여줍니다. 만약 데이터를 직접 반환하고 싶다면 메서드 위에 @ResponseBody를 추가로 붙여야 합니다.
  • @RestController (RESTful 웹 서비스 컨트롤러)
    최근 많이 사용되는 방식으로, 화면이 아닌 데이터 그 자체를 응답합니다.

    • 반환 값 : 객체(DTO)나 리스트 등을 반환하면, Spring이 이를 자동으로 JSON 형식으로 변환하여 HTTP 응답 본문(Body)에 담아 보냅니다.
    • 작동 방식 : @Controller에 @ResponseBody가 합쳐진 형태입니다. 모든 메서드에 일일이 @ResponseBody를 붙일 필요가 없어 편리합니다.
    • 용도 : 프론트엔드(React, Vue)와 백엔드가 분리된 구조나, 모바일 앱과의 통신에서 주로 사용합니다.
  • 웹 페이지를 직접 띄워줘야 한다면 @Controller, 스마트폰 앱이나 자바스크립트(Ajax)에 데이터만 쏴줘야 한다면 @RestController를 선택


3-4.  enum을 왜 써요? 그냥 String "RUNNING", "BOXING" 쓰면 안 돼요?

  • String은 오타나 잘못된 값이 들어와도 막을 수 없어서 안정성이 떨어진다. 그래서 정해진 값만 써야 하는 경우 enum을 사용한다.

  • enum은 정해진 값만 사용하게 강제해서 오타와 잘못된 데이터를 막고, 코드의 의미와 안정성을 높이기 위해 사용한다.


3-5.  메모리 저장소의 한계는 뭐예요? (힌트: 서버 재시작)

  • 메모리 저장소는 데이터를 RAM(메모리)에만 저장하기 때문에 서버가 종료되거나 재시작되면 저장된 데이터가 모두 사라진다는 한계가 있다.
  • 서버 여러 대면 데이터 공유 안됨
  • 프로그램 종료 시 데이터 삭제
  • 데이터 검색/정렬 한계
  • 대용량 처리 어려움
  • 동시성 문제 가능
  • 그래서 실제 서비스에선 MySQL, PostgreSQL, MongoDB같은 DB에 저장한다.

3-6.  ORM이 무엇인가? SQL을 직접 안 쓰는게 왜 좋은지? 단점은 없는지?

ORM (Object-Relational Mapping)

  • Java 객체 ↔ DB 테이블을 자동으로 매핑해주는 기술
  • 객체(Object) : 클래스, 인스턴스, 상속, 참조 등.
  • 관계형 데이터베이스(RDB) : 테이블, 로우(Row), 컬럼(Column), 외래키(FK) 등.
  • 매핑(Mapping) : 클래스는 테이블에, 인스턴스는 로우에, 필드는 컬럼에 대응됩니다.

ORM의 장점

  • 생산성 향상 : 반복적인 CRUD(Create, Read, Update, Delete)용 SQL을 작성하지 않아도 되므로 비즈니스 로직에 집중할 수 있습니다.
  • 유지보수 용이 : 테이블 스키마가 변경되어도 객체 모델만 수정하면 되므로 코드 관리가 효율적입니다.
  • 데이터베이스 독립성 : 특정 DB 엔진(MySQL, Oracle, PostgreSQL 등)에 종속되지 않고 설정 변경만으로 DB 교체가 수월해집니다.
  • 코드의 가독성 : SQL 문법이 아닌 프로그래밍 언어의 메서드로 데이터를 조작하여 가독성이 높습니다.

ORM의 단점 및 한계

  • 복잡한 쿼리 처리 : 통계 쿼리나 고도의 최적화가 필요한 복잡한 조인(Join)문은 ORM만으로 구현하기 어렵거나 성능이 떨어질 수 있습니다.
  • 학습 곡선 : 내부 작동 원리나 성능 최적화(N+1 문제 등)를 이해하기 위해 별도의 학습이 필요합니다.
  • 성능 오버헤드 : 직접 SQL을 작성하는 것보다 추상화 계층을 한 번 더 거치기 때문에 미세한 성능 차이가 발생할 수 있습니다.

대표적인 ORM 프레임워크

  • Java : JPA(Java Persistence API), Hibernate (가장 대표적)
  • Python : Django ORM, SQLAlchemy
  • JavaScript (Node.js) : Sequelize, TypeORM, Prisma
  • Ruby : Active Record

3-7.  JPA vs Hibernate vs Spring Data JPA - 이 셋의 관계

JPA (Java Persistence API) - "표준 인터페이스"

  • JPA는 기술 그 자체가 아니라 자바에서 ORM 기술을 어떻게 사용해야 하는지 정의한 인터페이스의 집합입니다.
  • 역할 : 자바 객체와 DB를 매핑하기 위한 규칙(가이드라인)을 제공합니다.
  • 특징 : 인터페이스이기 때문에 실제 코드가 구현되어 있지 않습니다. 따라서 JPA만으로는 아무런 동작을 할 수 없습니다.
  • 핵심 요소 : @Entity, @Id, EntityManager 등이 여기에 포함됩니다.

Hibernate (하이버네이트) - "구현체"

  • Hibernate는 JPA라는 인터페이스를 실제로 구현한 프레임워크입니다.
  • 역할 : JPA가 정의한 명세에 따라 실제로 자바 객체를 DB에 저장하고, SQL을 생성하며, 매핑 작업을 수행하는 핵심 엔진입니다.
  • 특징 : JPA가 나오기 전부터 존재했던 독자적인 ORM 프레임워크였으며, 현재는 JPA의 표준 구현체 중 가장 많이 사용됩니다. (이 외에도 EclipseLink, DataNucleus 등이 있지만 Hibernate가 사실상 표준입니다.)

Spring Data JPA - "추상화 라이브러리"

  • 역할 : 개발자가 EntityManager를 직접 다루지 않아도 Repository 인터페이스만 정의하면 구현체를 자동으로 생성해 줍니다.
  • 특징 : 내부적으로는 여전히 Hibernate(JPA 구현체)를 사용합니다. 즉, Spring Data JPA는 Hibernate를 한 번 더 감싸서 사용하기 편하게 만든 '편의 도구'입니다.
  • 핵심 요소 : JpaRepository 인터페이스, 메서드 이름으로 쿼리 생성 기능 등.

3-8.  영속성 컨텍스트 - 1차 캐치, 변경 감지

영속성 컨텍스트는 JPA가 entity를 저장,관리하는 공간

1차 캐시 (First Level Cache)

  • 영속성 컨텍스트 내부에는 엔티티를 보관하는 저장소가 있는데, 이를 1차 캐시라고 합니다. 맵(Map) 구조로 되어 있으며, Key는 @Id로 매핑한 식별자이고 Value는 엔티티 인스턴스 자체입니다.


  • 조회 성능 최적화 : 데이터를 조회할 때 DB를 바로 뒤지는 것이 아니라, 먼저 1차 캐시를 확인합니다.

    • 캐시에 데이터가 있다면? -> DB를 거치지 않고 즉시 반환 (매우 빠름).
    • 캐시에 데이터가 없다면? -> DB에서 조회 후 1차 캐시에 저장한 뒤 반환.
  • 객체 동일성 보장 : 같은 식별자로 조회한 객체는 항상 같은 인스턴스임을 보장합니다. a == b가 true가 되는 것이죠.


변경 감지 (Dirty Checking)

  • 보통 데이터베이스의 데이터를 수정하려면 UPDATE 쿼리를 직접 작성해야 합니다. 하지만 JPA를 사용하면 객체의 값만 바꿔도 DB에 반영됩니다. 이를 변경 감지라고 합니다.


  • 작동 원리 (스냅샷 활용)

    • 스냅샷 저장 : 엔티티가 영속성 컨텍스트에 처음 들어올 때(1차 캐시에 저장될 때), 그 당시의 상태를 복사해서 별도의 스냅샷으로 보관합니다.
    • 플러시(Flush) 시점 : 트랜잭션이 커밋되거나 플러시가 호출되면, JPA는 현재 엔티티의 상태와 처음 보관했던 스냅샷을 일일이 비교합니다.
    • 쿼리 자동 생성 : 비교 결과 변경된 부분이 있다면, JPA가 자동으로 UPDATE SQL을 생성해서 쓰기 지연 SQL 저장소에 쌓아두었다가 DB로 보냅니다.
    • 중요 : 변경 감지는 영속성 컨텍스트가 관리하는 영속 상태의 엔티티에만 적용됩니다. 준영속 상태나 비영속 상태의 객체는 값을 바꿔도 DB에 반영되지 않습니다.
  • 왜 이렇게 설계되었을까?

    • 이 기능들 덕분에 개발자는 데이터베이스를 마치 자바 컬렉션(List 등)처럼 다룰 수 있게 됩니다.
    • List에서 객체를 꺼내 값을 수정한다고 해서 별도의 save()를 호출하지 않듯, JPA도 트랜잭션 범위 안에서 객체를 수정하면 알아서 처리해줍니다.
    • 이는 앞서 언급된 '패러다임의 불일치'를 해결하여, 개발자가 SQL 중심이 아닌 비즈니스 로직(객체) 중심으로 사고하게 도와줍니다.

3-9. REST API

HTTP를 이용해서 데이터를 주고받는 방식의 규칙/약속

1.REST API의 3대 핵심 요소

    1. 자원 (Resource) - URI: 모든 자원은 고유한 ID를 가지며, 서버의 /users, /posts와 같은 엔드포인트로 표현됩니다.
    1. 행위 (Verb) - HTTP Method: 자원에 대한 조작은 HTTP 메서드를 통해 결정합니다.
    • GET: 조회 (Read)
    • POST: 생성 (Create)
    • PUT/PATCH: 수정 (Update)
    • DELETE: 삭제 (Delete)
    1. 표현 (Representation): 자원의 상태를 어떻게 보낼지 결정합니다. 현대에는 대부분 JSON 형식을 사용합니다.

2.REST의 주요 특징

    1. Stateless (무상태성) : 서버는 클라이언트의 상태를 저장하지 않습니다. 각 요청은 독립적이며 필요한 모든 정보를 포함해야 합니다.
    1. Cacheable (캐시 가능) : HTTP의 표준 캐싱 기능을 사용할 수 있어 대량의 트래픽을 효율적으로 처리합니다.
    1. Client-Server 구조 : 서버는 API 제공 및 비즈니스 로직을 담당하고, 클라이언트는 사용자 인터페이스를 담당하여 역할을 명확히 분리합니다.

3.RESTful한 설계를 위한 규칙

  • 명사 사용 : /getRecords (X) → /records (O). 행위는 HTTP 메서드로 표현합니다.
  • 계층 관계 : /users/1/orders (1번 사용자의 주문 목록).
  • 소문자 사용 : URI에는 가급적 대문자를 사용하지 않습니다.
  • 언더바(_) 대신 하이픈(-) 사용 : 가독성을 위해 하이픈을 사용합니다.
  • 파일 확장자 포함 금지 : .php, .jsp 등을 URI에 포함하지 않습니다.

4.REST API vs SSR



3-10.  프론트  -  웹스톰,  VSCode,  cursor


웹스톰

  • IntelliJ 만든 JetBrains 제품
  • JS/TS 전용 IDE
  • 설치하자마자 자동완성, 리팩토링, 디버깅 다 됨 (플러그인 필요 없음)
  • 인텔리J랑 UI/단축키 거의 동일해서 네가 적응하기 제일 편함
  • 유료인데 학생 이메일 있으면 무료

VSCode

  • Microsoft 만든 무료 텍스트 에디터
  • 세계에서 가장 많이 쓰는 에디터
  • 기본 기능은 심플하고, 플러그인 설치해서 기능 추가하는 구조
  • HTML/CSS/JS/Java 다 됨
  • 무료

Cursor

  • VSCode를 기반으로 만든 에디터
  • AI(Claude, GPT)가 에디터 안에 내장돼 있음
  • 코드 자동완성, 코드 설명, 버그 수정 제안을 에디터 안에서 바로 해줌
  • 무료 플랜 있는데 사용량 제한 있음
  • VSCode 플러그인 그대로 쓸 수 있음

3-11.  DTO(Data Transfer Object)란?

직역하면 '데이터 전송 객체', 말 그대로 프로세스 간(또는 레이어 간) 데이터를 이동시킬 때 오직 데이터만 담아서 나르는 껍데기 상자라고 생각하면 쉽다.

  • 가장 중요한 핵심은 "어떤 비즈니스 로직(기능)도 가지지 않는다"는 점이다.
    오직 Getter/Setter(또는 Java 14+의 Record)와 필드(변수)만 가집니다.

왜 쓰는가?

  • 레이어 간의 결합도 분리 (Domain 보호)

    • DB 테이블과 1:1로 매핑되는 Entity 객체는 시스템의 가장 핵심적인 도메인(Domain)이자 심장입니다.
    • 만약 UI(View)단이나 Controller단에서 화면 요구사항이 바뀔 때마다 Entity의 필드를 바꾸거나 지운다면 DB 스키마까지 흔들리게 됩니다.
    • DTO를 중간에 두면, 화면이 아무리 바뀌어도 Entity(DB)는 안전하게 보호됩니다.
  • 클라이언트 요구사항에 맞춘 데이터 성형

    • 사용자가 회원가입을 할 때 보내는 데이터(ID, 비밀번호, 비밀번호 확인)와, 로그인을 할 때 보내는 데이터(ID, 비밀번호)는 다릅니다.
    • 하나의 Entity로 이 모든 걸 처리할 수 없기 때문에 UserJoinRequestDto, UserLoginRequestDto 같이 목적에 딱 맞게 쪼갠 상자(DTO)를 만들어서 통신하는 것입니다.
  • 불필요한 정보 노출 방지 (보안)

    • DB에는 유저의 password나 socialSecurityNumber(주민번호) 같은 민감한 정보가 들어있습니다.
    • 만약 Entity를 그대로 JSON으로 응답(Response)해 버리면 해커에게 민감 정보가 그대로 유출됩니다.
    • DTO를 사용하면 딱 화면에 보여줄 id, name, nickname만 골라 담아서 안전하게 보낼 수 있습니다.