스프링 부트 백엔드 개발 강좌, 서버와 클라이언트

안녕하세요! 이번 강좌에서는 스프링 부트(Spring Boot)를 사용한 백엔드 개발에 대해 자세히 알아보겠습니다. 서버와 클라이언트 간의 상호작용을 이해하고, 실제 애플리케이션을 만들어 볼 것입니다. 본 강좌는 초급자부터 중급자까지 모두에게 유용하도록 구성하였습니다.

1. 스프링 부트란?

스프링 부트는 스프링 프레임워크를 기반으로 한 애플리케이션 프레임워크로, 복잡한 설정 없이 빠르게 스프링 애플리케이션을 만들 수 있도록 도와줍니다. 스프링 부트는 다음과 같은 특징을 가지고 있습니다:

  • 설정 최소화: 자동 설정 기능을 통해 설정을 최소화할 수 있습니다.
  • 독립 실행 가능: 내장된 톰캣, 제티 또는 언더토우를 사용하여 독립 실행형 애플리케이션으로 실행할 수 있습니다.
  • 스타터 패키지: 자주 사용하는 라이브러리를 쉽게 사용할 수 있도록 미리 설정된 스타터 패키지를 제공합니다.
  • 생산성 향상: 개발자가 더 빠르고 쉽게 코드를 작성할 수 있도록 여러 가지 기능을 제공합니다.

2. 서버와 클라이언트의 개념

서버와 클라이언트는 네트워크에서 데이터 통신의 기본 단위입니다. 클라이언트는 서비스를 요청하는 역할을 하며, 서버는 클라이언트의 요청에 응답하는 역할을 합니다. 다음과 같이 더 자세히 설명할 수 있습니다:

  • 클라이언트: 웹 브라우저, 모바일 앱 등 사용자가 직접 상호작용하는 인터페이스를 제공합니다. 클라이언트는 서버에 HTTP 요청을 보내고, 서버로부터 HTTP 응답을 받습니다.
  • 서버: 클라이언트의 요청을 처리하는 프로그램입니다. 서버는 데이터베이스와 연동하여 클라이언트 요청에 대한 결과를 반환합니다.

3. 스프링 부트 설치하기

스프링 부트를 사용하기 위해서는 JDK, 스프링 부트, 그리고 개발 환경인 IDE가 필요합니다. 다음 절차에 따라 설치할 수 있습니다:

  1. Java Development Kit (JDK) 설치: JDK 11 이상을 설치합니다. Oracle JDK 또는 OpenJDK를 사용할 수 있습니다.
  2. IDE 설치: IntelliJ IDEA, Eclipse 또는 Spring Tool Suite(STS)와 같은 IDE를 설치합니다.
  3. 스프링 부트 CLI 설치 (선택적): 커맨드라인에서 스프링 부트 프로젝트를 생성하기 위해 스프링 부트 CLI를 설치할 수 있습니다.

4. 스프링 부트 프로젝트 생성하기

스프링 부트 프로젝트는 여러 가지 방법으로 생성할 수 있습니다. 가장 편리한 방법은 Spring Initializr를 사용하는 것입니다. 다음과 같은 절차로 프로젝트를 생성해 봅시다:

  1. Spring Initializr 접속: start.spring.io 에 접속합니다.
  2. 프로젝트 설정: 프로젝트 메타데이터를 설정합니다. Maven Project, Java, 그리고 적절한 Spring Boot 버전을 선택합니다.
  3. 종속성 추가: 스프링 웹, JPA, H2 데이터베이스 등 필요한 종속성을 추가합니다.
  4. 프로젝트 다운로드: Generate 버튼을 클릭하여 프로젝트를 다운로드합니다.

5. 간단한 RESTful API 만들기

이제 스프링 부트를 사용하여 간단한 RESTful API를 만들어 보겠습니다. 여기서는 자원으로 ‘도서’를 관리하는 API를 구현해 보겠습니다.

5.1 도메인 모델 생성

먼저 ‘도서’ 도메인 모델을 정의합니다. 도서의 속성으로는 ID, 제목, 저자, 출판 연도를 포함할 것입니다.

package com.example.demo.model;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Book {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String title;
    private String author;
    private int year;

    // getter와 setter 생략
}
            

5.2 리포지토리 인터페이스 생성

JPA를 사용하여 데이터베이스와 상호작용하는 리포지토리 인터페이스를 생성합니다.

package com.example.demo.repository;

import com.example.demo.model.Book;
import org.springframework.data.jpa.repository.JpaRepository;

public interface BookRepository extends JpaRepository<Book, Long> {
}

            

5.3 서비스 클래스 생성

비즈니스 로직 처리를 위한 서비스 클래스를 생성합니다. 이 클래스는 리포지토리를 활용하여 도서 데이터를 추가하고 조회할 수 있습니다.

package com.example.demo.service;

import com.example.demo.model.Book;
import com.example.demo.repository.BookRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class BookService {
    @Autowired
    private BookRepository bookRepository;

    public List<Book> getAllBooks() {
        return bookRepository.findAll();
    }

    public Book addBook(Book book) {
        return bookRepository.save(book);
    }
}
            

5.4 컨트롤러 클래스 생성

클라이언트의 요청을 처리하기 위한 REST 컨트롤러를 생성합니다. 이 컨트롤러를 통해 API의 엔드포인트를 정의할 수 있습니다.

package com.example.demo.controller;

import com.example.demo.model.Book;
import com.example.demo.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api/books")
public class BookController {
    @Autowired
    private BookService bookService;

    @GetMapping
    public List<Book> getAllBooks() {
        return bookService.getAllBooks();
    }

    @PostMapping
    public Book addBook(@RequestBody Book book) {
        return bookService.addBook(book);
    }
}
            

5.5 애플리케이션 실행하기

이제 모든 설정이 완료되었습니다. DemoApplication 클래스에서 main 메소드를 실행하여 애플리케이션을 시작합니다.

6. Postman을 사용해 API 테스트하기

Postman을 이용하여 우리가 만든 API가 제대로 작동하는지 테스트해 보겠습니다. 다음과 같은 절차를 따릅니다:

  1. Postman 실행: Postman 애플리케이션을 열고 새로운 요청을 만듭니다.
  2. GET 요청하기: URL에 http://localhost:8080/api/books를 입력하고 GET 요청을 보냅니다. 응답으로 현재 도서 목록이 나와야 합니다.
  3. POST 요청하기: 새로운 도서를 추가하기 위해 URL에 http://localhost:8080/api/books를 입력하고, POST 요청을 설정합니다. Body를 JSON 형식으로 설정하여 도서 정보를 입력합니다.

7. 데이터베이스 연동

이번 섹션에서는 스프링 부트를 H2 데이터베이스와 연동하는 방법에 대해 알아보겠습니다. H2 데이터베이스는 인메모리 데이터베이스로, 테스트 및 개발에 적합합니다.

7.1 데이터베이스 설정

스프링 부트 애플리케이션의 application.properties 파일에서 H2 데이터베이스 설정을 추가합니다:

spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.h2.console.enabled=true
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
            

7.2 데이터 초기화

애플리케이션 실행 시 기본 데이터를 추가하려면 data.sql 파일을 사용하여 초기 데이터를 설정할 수 있습니다.

INSERT INTO book (title, author, year) VALUES ('이것이 자바다', '신용권', 2020);
INSERT INTO book (title, author, year) VALUES ('Spring in Action', 'Craig Walls', 2018);
            

8. 예외 처리

생성된 API에서 발생할 수 있는 예외를 처리하는 방법에 대해 알아보겠습니다. 스프링에서는 @ControllerAdvice를 사용하여 전역적으로 예외 처리를 할 수 있습니다.

package com.example.demo.exception;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

@ControllerAdvice
public class GlobalExceptionHandler {
    
    @ExceptionHandler(Exception.class)
    public ResponseEntity<String> handleException(Exception e) {
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());
    }
}
            

이렇게 설정하면 모든 예외가 처리되어 클라이언트에 적절한 응답을 반환할 수 있습니다.

9. 클라이언트와의 통신

이번 섹션에서는 클라이언트와 서버 간의 통신 방법에 대해 알아보겠습니다. 일반적으로 클라이언트는 REST API를 통해 서버와 상호작용합니다. 일반적인 요청 방법은 다음과 같습니다:

  • GET: 데이터 조회
  • POST: 데이터 생성
  • PUT: 데이터 수정
  • DELETE: 데이터 삭제

10. 클라이언트 애플리케이션 구현

서버 쪽에서 API가 성공적으로 구현되었으니, 이제 클라이언트 애플리케이션을 만들어보겠습니다. 여기서는 간단한 HTML과 JavaScript 기반의 프론트엔드를 만들어 REST API와 통신해 보겠습니다.

10.1 HTML 구조 만들기

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>도서 목록</title>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
    <h1>도서 목록</h1>
    <table id="bookTable">
        <tr><th>제목</th><th>저자</th><th>연도</th></tr>
    </table>
    <script>
        function fetchBooks() {
            $.get("http://localhost:8080/api/books", function(data) {
                data.forEach(function(book) {
                    $('#bookTable').append(`<tr><td>${book.title}</td><td>${book.author}</td><td>${book.year}</td></tr>`);
                });
            });
        }
        $(document).ready(function() {
            fetchBooks();
        });
    </script>
</body>
</html>
            

11. 보안

애플리케이션에서 보안은 매우 중요합니다. 스프링 시큐리티(Spring Security)를 통해 인증 및 권한 부여를 구현할 수 있습니다. 다음은 간단한 보안 설정 예시입니다:

package com.example.demo.config;

import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
            .authorizeRequests()
            .anyRequest().authenticated()
            .and()
            .httpBasic();
    }
}
            

결론

이 강좌를 통해 스프링 부트를 이용한 백엔드 개발 방법과 서버와 클라이언트 간의 통신 원리를 배웠습니다. 실제 애플리케이션을 개발하면서 다양한 상황을 경험해 보시기 바랍니다. 앞으로도 더 많은 지식을 쌓고, 지속적으로 학습해 나가시길 바랍니다. 감사합니다!