Instagram Clone Coding Backend #1 프로젝트 시작하기

HY·2022년 3월 20일
1

Instagram Clone Coding

목록 보기
2/3

🔨 프로젝트 생성

🔍 Spring Initializr

spring initializr

위 사이트에서 스프링 부트 프로젝트를 쉽게 생성할 수 있다.

Maven vs Gradle
프로젝트를 관리해 주는 도구로 Maven은 XML을 기반으로, Gradle은 Groovy라는 Java와 유사한 언어를 기반으로 빌드 처리를 작성한다. 요즘은 Gradle을 많이 사용하는 추세라고 한다. 이 프로젝트에서는 Gradle을 사용했다.

Dependency
Spring Web, JPA, MySQL driver, Security 등 필요한 라이브러리를 추가했다.

그 외에 언어, Spring Boot 버전, Project 정보들을 입력하면 프로젝트를 생성할 수 있다.

🔍 IntelliJ에서 생성하기

Spring Initilizr 말고 IntelliJ에서도 프로젝트를 생성할 수 있다. Gradle 프로젝트 생성 후, build.gradle에서 설정을 해주면 된다.

먼저 아래 코드를 build.gradle 앞부분에 추가해 준다.

buildscript {
	ext {
    	springBootVersion = 'SPRING BOOT VERSION'
    }
    repositories {
    	mavenCentral()
    }
    dependencies {
    	classpath("org.springframework.boot:spring-bootgradle-plugin:${springBootVersion}")
    }
}

apply plugin: 'java'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

buildscript 먼저 살펴보면, ext는 전역변수 설정, repositories는 각종 의존성(라이브러리)들을 어떤 원격 저장소에서 받을지를 정한다. 기본적으로 mavenCentral을 많이 사용한다고 한다. dependencies는 프로젝트 개발에 필요한 의존성을 선언하는 곳이다.
spring-boot-gradle-plugin의 설정해 준 버전(SPRING BOOT VERSION에 넣기)를 의존성으로 받겠다는 의미이다.

apply plugin 부분은 앞서 선언한 플러그인 의존성들을 적용할 것인지를 결정하는 코드다.

찾아보니, buildscript와 apply plugin 부분은 plugins 블록으로 간편하게 표현할 수 있다고 한다. (참고: https://doughman.tistory.com/19)

그리고, 마지막으로 dependecies 부분에 필요한 의존성을 선언해 준다.

dependencies {
 compile('org.springframework.boot:spring-boot-starter-web')
 testCompile('org.springframework.boot:spring-boot-startertest')
}

그 외 필요한 의존성이 있으면 추가한다.

다 작성하면 변경 사항을 반영해 준다.

✅ 프로젝트 실행

🔍 IntelliJ에서 실행하기

간단하게 main method를 실행(run)하면 된다.

🔍 터미널에서 실행하기

프로젝트 폴더로 이동해서 다음 명령어를 실행한다. (빌드 후, 생성된 프로젝트 jar 파일을 실행)

./gradlew clean build
java -jar build/libs/instagram-backend-0.0.1-SNAPSHOT.jar

💻 웹 개발 방식

스프링으로 웹 개발을 한다면 다음 3가지 방법을 사용할 수 있다.

  1. 정적 컨텐츠
    단순하게 정적인 html 파일만 보내는 것이다.
    프로젝트의 resources/static 폴더에 html 파일을 넣고 local에서 서버를 돌리면 localhost:8080/파일이름.html 으로 실행할 수 있다.

  2. MVC
    어플리케이션을 Model, View, Controller 세 부분으로 나누어 View 에서는 화면 출력, Model 에서는 데이터 가공, Controller에서는 Model과 View를 이어주는 역할을 한다.

  3. API
    데이터를 json 등의 파일로 client에 전달하는 방식이다.

이 프로젝트에서는 API 서버를 만들어 JSON 파일로 데이터를 보내주었는데, 맨 처음 시작할 때는 웹 개발에 대한 지식이 없어 프론트엔드 서버와 백엔드 서버가 구체적으로 어떤 일을 하고 어떤 식으로 작동이 되는지 잘 몰라 공부가 필요했다.

🔍 웹 렌더링 방식

브라우저는 HTML, CSS, Javascript와 같은 파일을 받아 화면에 표시한다.

화면에 표시할 때, 서버에서 완전히 만들어진 HTML 페이지를 보내주는 SSR 방식이 있고, 동적으로 DOM에 렌더링 해주기 위한 Javascript 파일을 따로 받아 클라이언트(브라우저)에서 해석해 렌더링해주는 CSR 방식이 있다.

SSR (Server-Side Rendering)

서버로부터 완전하게 만들어진 html 파일을 받아와 페이지 전체를 렌더링하는 방식이다.

JSP, Servlet 등도 이 방식이라고 한다.

Browser <-> Web Server <-> Database

React, Angular, View 등 SPA (Single Page Application) 프레임워크가 발전하면서 CSR 방식을 많이 쓰다가 CSR 방식의 단점 때문에 요즘은 SSR 방식도 많이 쓰고 있다고 한다. (Browser <-> Frontend <-> Backend <-> Database)

CSR (Client-Side Rendering)

사용자의 요청에 따라 필요한 부분만 응답 받아 렌더링 하는 방식이다.
처음에 서버에서 HTML 파일과 함께 동적으로 렌더링해주기 위한 Javascript 파일을 보낸다. 클라이언트가 파일을 받으면 사용자의 상호작용에 따라 JS 파일이 동적으로 렌더링하고 추가로 필요한 데이터가 있으면 서버에 요청해서 데이터를 받아온 다음, 이것들을 기반으로 해서 동적으로 HTML을 생성해 보여준다.

Browser <-> Frontend Server
Browser <-> Backend Server (API Server) <-> Database

처음 Javascript 파일을 보내줄 때, 어플리케이션에 필요한 로직들 뿐만 아니라 어플리케이션을 구동하는 프레임워크와 라이브러리의 소스 코드들도 모두 포함되어 있어 초기 로딩 시간이 오래 걸릴 수 있다.

이 인스타그램 클론 프로젝트에서는 프론트엔드로는 React를 사용했고 백엔드에서는 화면에 필요한 데이터들을 보내주기 위해 API 서버를 만들었다.

📁 프로젝트 구조

프로젝트 구조에 대해서는 책을 많이 참고 했다.

출처 : 스프링 부트와 AWS로 혼자 구현하는 웹 서비스

Web Layer

  • 흔히 사용하는 컨트롤러(@Controller)와 JSP/Freemarker 등의 뷰 템플릿 영역

Service Layer

  • @Service에 사용되는 서비스 영역
  • Controller와 Dao의 중간 영역에서 사용
  • @Transactional이 사용되어야하는 영역

Repository Layer

  • Database와 같이 데이터 저장소에 접근하는 영역

Domain Model

  • 도메인(개발 대상)을 모든 사람이 동일한 관점에서 이해할 수 있고 공유할 수 있도록 단순화 시킨 것
  • 택시 앱이라고 하면 배차, 탑승, 요금 등이 도메인
  • @Entity가 사용되는 영역 (JPA, 테이블과 1:1 매칭)

Dtos

  • 계층 간에 데이터 교환을 위한 객체 (Data Transfer Object)

정리하자면 위와 같은 흐름을 갖는다.
쉽게 생각하자면,

  • Domain (DB의 테이블과 1:1 매칭 될 Entity Class)
  • Repository (DB에 접근해 도메인 객체를 DB에 저장하고 관리해주는 영역)
  • Service (핵심 비즈니스 로직 구현, Transactional)
  • Controller (해당 요청 url에 따라 적절하게 응답 - MVC 모델에서는 적절한 view와 mapping, RestController의 경우 적절한 ResponseEntity(DTO)를 body에 담아 Client에 반환, service의 메서드를 이용함)

로 나뉠 수 있다.

이걸 바탕으로 기본적인 폴더 구조는 다음과 같이 구성했다.

├── domain
├── service
└── web
    ├── controller
    └── dto

여기에서 domain 폴더에 entity와 해당하는 repository를 같이 넣었다.

사실 프로젝트 구조는 처음 글로만 봤을 때는 이해가 잘 안 가서 예제를 보면서 그냥 이런 식으로 사용하나 보다 하고 넘어갔던 것 같은데 다음에 좀 더 알아보고 정리를 해봐도 좋을 것 같다.

0개의 댓글