Home > CS > 2024 > 💾 [CS] API 설계, 계층형 아키텍처, 트랜잭션, 엔티티(Entity), 비즈니스 로직과 비즈니스 규칙의 차이점.

💾 [CS] API 설계, 계층형 아키텍처, 트랜잭션, 엔티티(Entity), 비즈니스 로직과 비즈니스 규칙의 차이점.
CS

💾 [CS] API 설계, 계층형 아키텍처, 트랜잭션, 엔티티(Entity), 비즈니스 로직과 비즈니스 규칙의 차이점.

1️⃣ API 설계.

  • API 설계 는 클라이언트와 서버 간에 데이터를 주고받기 위한 인터페이스(즉, API)를 정의하고 설계하는 과정입니다.
  • API는 응용 프로그램 간의 상호작용을 가능하게 하며, API 설계는 이러한 상호작용이 효율적이고 사용하기 쉬우며 확장 가능하도록 하는 것을 목표로 합니다.
  • 특히 RESTful API와 같은 웹 API는 웹 애플리케이션, 모바일 애플리케이션, 서비스 간의 통신을 중점적으로 다룹니다.

1. API 설계의 핵심 요소.

API 설계는 사용자와 시스템 간의 명확하고 일관된 커뮤니케이션을 위한 몇 가지 중요한 요소를 고려해야 합니다.

1. 엔드포인트(Endpoint) 정의.

  • API 엔드포인트는 API가 제공하는 자원(리소스)에 접근하기 위한 URL 경로입니다.
    • 예를 들어 /users/product/123는 각각 사용자 목록에 접근하거나 특정 제품 정보를 가져오는 엔드포인트가 될 수 있습니다.
  • 명확하고 직관적인 URL 경로 를 설계하는 것이 중요합니다.
    • URL은 해당 리소스를 잘 표현하고 이해하기 쉽게 설계되어야 합니다.
예시
  • GET /users
    • 사용자 목록을 가져옴.
  • POST /users
    • 새로운 사용자 생성.
  • GET /users/{id}
    • 특정 사용자 정보 조회.
  • PUT /users/{id}
    • 사용자 정보 수정.
  • DELETE /users/{id}
    • 사용자 삭제.

2. HTTP 메서드.

  • HTTP 메서드는 리소스에 대해 어떤 동작을 수행할지를 나타냅니다.
    • 주로 사용하는 메서드
      • GET : 리소스를 조회할 때 사용합니다.
      • POST : 새로운 리소스를 생성할 때 사용합니다.
      • PUT : 기존 리소스를 수정할 때 사용합니다.
      • DELETE : 리소스를 삭제할 때 사용합니다.
      • PATCH : 리소스의 일부를 수정할 때 사용합니다.

각 엔드포인트와 HTTP 메서드를 조합하여 API의 기능을 구성합니다.

3. 데이터 형식.

  • API는 데이터를 주고받는 방식으로 JSON 이나 XML 과 같은 형식을 주로 사용합니다.
    • 대부분의 현대 API는 가벼운 JSON 형식을 기본으로 사용합니다.
  • 응답의 데이터 형식은 클라이언트가 쉽게 파싱할 수 있는 구조로 정의되어야 합니다.

예시(JSON 데이터)

{
    "id": 123,
    "name": "Kobe",
    "email": "kobe@example.com"
}

4. 요청 및 응답 구조.

  • 요청(Request) 은 API로 데이터를 보내는 방식입니다.
    • 요청 본문에는 JSON 또는 폼 데이터가 포함될 수 있으며, 쿼리 파라미터나 URL 파라미터로도 데이터를 전달할 수 있습니다.
  • 응답(Response) 은 요청에 대한 서버의 응답으로, 상태 코드와 함께 데이터를 반환합니다.

요청(Request)

POST /users
Content-Type: application/json

{
    "name": "kobe",
    "email": "kobe@example.com"
}

응답(Response)

HTTP/1.1 201 Created
Content-Type: application/json

{
    "id": 123,
    "name": "Kobe",
    "email": "kobe@example.com"
}

5. 상태 코드.

  • HTTP 상태 코드는 요청에 대한 결과를 나타내며, API 설계에서 중요한 부분을 차지합니다.
  • 성공 여부와 오류를 구분하는 데 사용됩니다.
    • 200 OK : 요청 성공.
    • 201 Created : 리소스 생성 성공.
    • 400 Bad Request : 잘못된 요청.
    • 401 Unauthorized : 인증 실패.
    • 403 Forbidden : 권한 부족.
    • 404 Not Found : 리소스가 존재하지 않음.
    • 500 Internal Server Error : 서버 오류.

응답 예시.

HTTP/1.1 404 Not Found

6. 요청 파라미터.

  • API에서 클라이언트가 데이터를 서버에 전달하는 방식으로 URL 파라미터, 쿼리 스트링, 요청 본문 등 다양한 방식이 있습니다.
    • 경로 변수(Path Variable) : URL 경로에 포함된 변수(/users/{id})
    • 쿼리 파라미터(Query Parameter) : URL 뒤에 붙는 ?key=value 형식의 파라미터(/users?sort=name)
    • 요청 본문(Request Body) : POST나 PUT 요청에서 데이터를 전송할 때 본문에 JSON이나 폼 데이터를 포함.

7. 보안.

  • API는 데이터를 보호하기 위해 인증과 권한 부여 기능을 갖추어야 합니다.
    • OAuth 2.0, JWT(Json Web Token)와 같은 기술을 통해 인증을 처리할 수 있습니다.
  • HTTPS를 통해 모든 통신을 암호화하는 것도 필수적인 보안 요소입니다.

8. 버전 관리.

  • API는 시간이 지나면서 업데이트되거나 변경될 수 있기 때문에, 버전 관리를 통해 하위 호환성을 유지하는 것이 중요합니다.
    • API 버전은 URL에 포함하는 방식으로 관리할 수 있습니다.

예시.

  • /v1/users : 버전 1의 API
  • /v2/users : 버전 2의 API

9. 에러 처리.

  • 클라이언트가 요청을 잘못 보냈거나 서버에서 문제가 발생했을 때, 적절한 에러 메시지와 상태 코드를 제공해야 합니다.
    • 이는 클라이언트가 오류를 쉽게 이해하고 대응할 수 있도록 돕습니다.

에러 응답 예시.

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
    "error": "Invalid input data",
    "message": "The email field is required"
}

10. 문서화.

  • API는 명확한 문서화가 필수입니다.
    • 클라이언트가 API를 올바르게 사용할 수 있도록 엔드포인트, 요청 방법, 파라미터, 응답 형식 등을 상세히 기술한 문서가 제공되어야 합니다.
    • 대표적인 API 문서화 도구로는 Swagger(OpenAPI)가 있습니다.

2. API 설계 원칙.

  • 1. 일관성
    • 모든 엔드포인트와 HTTP 메서드 사용에 일관성을 유지합니다.
      • 예를 들어, 리소스 생성은 항상 POST 메서드를, 조회는 GET 메서드를 사용하도록 일관성을 유지해야 합니다.
  • 2. RESTful 디자인
    • RESTful API 원칙에 따라 리소스를 URL로 나타내고, HTTP 메서드에 따라 행동을 정의합니다.
  • 3. 확장성
    • API는 확장 가능하도록 설계되어야 하며, 새로운 기능이 추가되거나 데이터 구조가 변경되더라도 기존 사용자에게 영향을 최소화해야 합니다.
  • 4. 사용자 친화적
    • API는 사용하기 쉽고 명확하게 설계되어야 하며, 직관적인 엔드포인트 구조와 적절한 에러 메시지를 제공해야 합니다.

3. API 설계 도구.

  • 1. Postman
    • API 테스트 및 요청/응답 시뮬레이션 도구.
    • 클라이언트 요청을 손쉽게 보내보고 응답을 확인할 수 있습니다.
  • 2. Swagger(OpenAPI)
    • API 문서화와 자동화된 테스트 도구.
    • API를 정의하고, 클라이언트가 사용할 수 있는 문서를 자동으로 생성해줍니다.
  • 3. Insomnia
    • Postman과 비슷한 API 테스트 도구로, 사용자 인터페이스가 직관적입니다.

4. 요약.

  • API 설계는 클라이언트와 서버 간의 데이터 통신 방식을 정의하는 과정으로, 엔드포인트, HTTP 메서드, 데이터 형식, 보안, 상태 코드 등의 요소를 고려해야 합니다.
  • RESTful API 원칙에 따라 설계되며, 직관적이고 확장 가능해야 하며, 명확한 문서화를 제공해야 합니다.
  • 보안 및 버전 관리를 통해 API의 유지보수와 확장을 쉽게 할 수 있도록 설계하는 것이 중요합니다.

2️⃣ 계층형 아키텍처(Layered Architecture)

  • 계층형 아키텍처(Layered Architecture) 는 소프트웨어 시스템을 여러 계층으로 나누어 설계하는 아키텍처 패턴입니다.
  • 이 패턴은 각각의 계층이 특정한 책임을 가지며, 각 계층은 자신이 맡은 기능을 처리하고 그 결과를 다른 계층에 전달하는 방식으로 작동합니다.
  • 계층형 아키텍처는 코드의 유지보수성, 재사용성 그리고 확장성 을 높이는 데 중요한 역할을 하며, 특히 엔터프라이즈 애플리케이션에서 많이 사용됩니다.

1. 계층형 아키텍처의 특징.

1. 책임 분리(Separation of Concerns).

  • 각 계층은 고유한 책임을 가지며, 다른 계층과는 특정한 방식만으로만 상호작용합니다.
    • 이로 인해 코드의 모듈화가 가능해지고, 각 계층이 독립적으로 개발되고 유지보수될 수 있습니다.

2. 계층 간 상호작용.

  • 각 계층은 하위 계층과만 상호작용합니다.
    • 예를 들어, UI 계층은 서비스 계층과만 상호작용하며, 서비스 계층은 데이터 접근 계층과만 상호작용합니다.
    • 이러한 상호작용 규칙은 계층 간의 결합도를 낮추고, 시스템을 더 유연하게 만들어줍니다.

3. 유지보수성.

  • 계층 간의 책임이 명확히 분리되므로, 특정 계층의 로직이 변경되더라도 다른 계층에 미치는 영향을 최소화할 수 있습니다.
    • 이를 통해 코드의 유지보수가 쉬워집니다.

4. 확장성.

  • 각 계층은 독립적으로 확장 가능합니다.
  • 특정 계층의 기능이 확장되어도 다른 계층에는 영향을 미치지 않으므로, 기능 추가 및 성능 개선이 용이합니다.

2. 계층형 아키텍처의 계층.

일반적으로 계층형 아키텍처는 다음과 같은 계층들로 나누어집니다.

1. 프레젠테이션 계층(Presentation Layer)

  • 사용자 인터페이스와 관련된 모든 기능을 처리하는 계층입니다.
  • 주로 웹 브라우저, 모바일 애플리케이션 등에서 사용자로부터 입력을 받고, 결과를 화면에 출력합니다.
  • Java 애플리케이션에서는 주로 Controller가 이 계층에 해당하며, HTTP 요청을 받아서 Service 계층에 전달하고, 그 결과를 사용자에게 반환합니다.

2. 서비스 계층(Service Layer)

  • 비즈니스 로직을 처리하는 계층으로, 애플리케이션의 주요 기능을 구현합니다.
  • 프레젠테이션 계층에서 들어온 요청을 처리하고, 데이터베이스와 상호작용하기 위해 데이터 접근 계층에 요청을 전달합니다.
  • 이 계층에서는 주로 트랜잭션 관리복잡한 비즈니스 로직을 처리합니다.

3. 비즈니스 도메인 계층(Domain Layer)

  • 도메인 모델과 비즈니스 로직이 포함된 계층입니다.
  • 이 계층은 애플리케이션의 핵심 개념을 나타내는 엔티티비즈니스 규칙을 관리합니다.
  • 비즈니스 도메인 계층은 다른 계층의 영향을 최소화하기 위해 독립적으로 존재하며, 객체 간의 관계 및 상태를 관리하는 역할을 합니다.

4. 데이터 접근 계층(Data Access Layer)

  • 데이터베이스와 상호작용하는 계층입니다.
  • 주로 Repository 또는 DAO(Data Access Object) 패턴을 사용하여 데이터베이스 CRUD(Create, Read, Update, Delete) 작업을 처리합니다.
  • 데이터베이스와 상호작용하는 로직은 이 계층에 집중되며, 비즈니스 로직과 분리되어 있습니다.

5. 외부 시스템 계층(External Layer) (선택적)

  • 외부 API나 다른 시스템과 통신하기 위한 계층입니다.
  • 외부 서비스나 API에 대한 호출은 이 계층에서 이루어집니다.

3. 계층 간 상호작용.

  • 각 계층은 자신의 상위 계층하위 계층에만 의존합니다.
  • 프레젠테이션 계층은 서비스 계층에 요청을 전달하고, 서비스 계층은 비즈니스 도메인과 데이터 접근 계층을 사용하여 작업을 처리합니다.

4. 계층형 아키텍처의 예시.

다음은 계층형 아키텍처를 구현한 예시입니다.

// Presentation Layer(Controller)

@RestController
@RequestMapping("/users")
public class UserController {
    
    private final UserService userService;
    
    @Autowired
    public UserController(UserService userService) {
        this.userService = userService;
    }
    
    @GetMapping("/{id}")
    public ResponseEntity<UserDTO> getUser(@PathVariable Long id) {
        UserDTO user = userService.getUserById(id);
        return ResponseEntity.ok(user);
    }
}

// Service Layer
@Service
public class UserService {
    
    private final UserRepository userRepository;
    
    @Autowired
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    
    public UserDTO getUserById(Long id) {
        User user = userRepository.findById(id)
            .orElseThrow(() -> new UserNotFoundException("User not found"));
        return new UserDTO(user);
    }
}

// Domain Layer
@Entity
public class User {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String email;
    
    // getters and setters
}

// Data Access Layer (Repository)
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}

5. 계층형 아키텍처의 장점.

  • 1. 유지보수 용이
    • 각 계층은 특정 기능에 대한 책임을 가지므로, 수정이 필요한 경우 해당 계층만 수정하면 됩니다.
    • 다른 계층에는 최소한의 영향을 미치므로 유지보수가 쉽습니다.
  • 2. 모듈화
    • 계층별로 기능이 분리되어 있으므로, 각 계층의 기능이 확장되더라도 다른 계층에 영향을 미치지 않기 때문에, 새로운 기능 추가나 성능 개선이 용이합니다.
  • 3. 확장성
    • 계층형 구조는 확장하기 쉽습니다.
    • 특정 계층의 기능이 확장되더라도 다른 계층에 영향을 미치지 않기 때문에, 새로운 기능 추가나 성능 개선이 용이합니다.
  • 4. 테스트 용이성
    • 각 계층이 분리되어 있어, 계층별로 단위 테스트를 작성하기 쉽습니다.
    • 예를 들어, 서비스 계층의 로직을 테스트할 때 데이터베이스에 접근할 필요 없이 Mock 객체를 사용하여 테스트할 수 있습니다.

6. 계층형 아키텍처의 단점.

  • 1. 복잡성 증가
    • 각 계층이 분리되어 있어 코드 구조가 복잡해질 수 있으며, 작은 애플리케이션에서는 불필요하게 복잡한 구조가 될 수 있습니다.
  • 2. 성능 저하
    • 계층 간의 상호작용이 빈번할 경우, 오버헤드가 발생할 수 있습니다.
    • 각 계층을 거쳐 요청이 처리되기 때문에 응답 시간이 길어질 수 있습니다.
  • 3. 추가 작업 필요
    • 계층별로 책임을 나누어 설계하다 보니, 코드량이 증가하고 추가적인 개발 작업이 필요할 수 있습니다.

7. 계층형 아키텍처의 활용 사례

  • 1. 엔터프라이즈 애플리케이션
    • 복잡한 비즈니스 로직과 데이터 처리가 중요한 대규모 애플리케이션에서 자주 사용됩니다.
  • 2. 웹 애플리케이션
    • 프론트엔드와 백엔드 간의 데이터 통신이 중요한 웹 애플리케이션에서 주로 사용됩니다,
      • 예를 들어, 전자 상거래 사이트나 CRM 시스템 같은 애플리케이션에 적합합니다.

7. 요약.

  • 계층형 아키텍처는 소프트웨어 시스템을 여러 계층으로 나누어, 각 계층이 특정한 책임을 가지도록 설계하는 아키텍처 패턴입니다.
  • 프레젠테이션, 서비스, 도메인, 데이터 접근 등의 계층이 있으며, 각 계층은 상위/하위 계층과만 상호작용합니다.
  • 유지보수성, 모듈성, 테스트 용이성 등의 장점이 있지만, 작은 애플리케이션에서는 복잡성이 높아질 수 있습니다.
  • 대규모 애플리케이션 및 엔터프라이즈 시스템에 적합한 아키텍처입니다.

3️⃣ 트랜젝션(Transaction)

  • 트랜젝션(Transaction) 은 데이터베이스 또는 시스템에서 하나의 작은 작업 단위를 말하며, 일련의 작업들이 모두 성공하거나 모두 실패하는 것을 보장하는 작업입니다.
  • 즉, 트랜잭션은 데이터베이스의 상태를 변경하는 여러 작업을 하나의 묶음으로 처리하여, 이 작업들을 모두 성공적으로 완료되면 그 결과가 데이터베이스에 반영되고, 그렇지 않으면 모든 변경 사항이 취소됩니다

1. 트랜젝션의 특징(ACID 특성)

트랜젝션은 ACID라는 네 가지 중요한 속성을 가져야 합니다.

  • 1. 원자성(Atomicity)
    • 트랜젝션 내의 작업은 모두 성공적으로 완료되거나, 전혀 완료되지 않은 상태가 되어야 합니다.
    • 트랜젝션 내의 하나라도 실패하면, 전체 트렌젝션은 실패한 것으로 간주되어 데이터베이스의 상태를 변경하기 이전의 상태로 되돌립니다.
  • 2. 일관성(Consistency)
    • 트랜젝션이 성공적으로 완료된 후에는 데이터베이스가 항상 일관된 상태를 유지해야 합니다.
    • 즉, 트랜잭션의 실행 전과 실행 후의 데이터베이스는 모든 제약 조건을 만족해야 합니다.
  • 3. 고립성(Isolation)
    • 동시에 실행되는 여러 트랜잭션들이 서로 영향을 미치지 않도록 고립된 상태로 실행되어야 합니다.
    • 하나의 트랜잭션이 완료되기 전까지 트랜잭션이 그 중간의 결과를 참조할 수 없으며, 동시에 실행되는 트랜잭션들이 데이터베이스에 일관성 없는 영향을 주지 않아야 합니다.
  • 4. 지속성(Durability)
    • 트랜잭션이 성공적으로 완료된 후, 그 결과는 영구적으로 데이터베이스에 반영되어야 합니다.
    • 시스템에 장애가 발생해도 트랜잭션 결과는 손실되지 않고 유지되어야 합니다.

2. 트랜잭션의 작업 흐름.

트랜잭션의 작업은 주로 두 가지 명령어로 구분됩니다.

  • 1. COMMIT
    • 트랜잭션 내의 작업이 성공적으로 완료되면, COMMIT을 통해 트랜잭션이 데이터베이스에 영구적으로 반영됩니다.
  • 2. ROLLBACK
    • 트랜잭션 내의 작업이 중간에 실패하면, ROLLBACK을 통해 트랜잭션을 시작하기 전의 상태로 되돌리며, 이때 모든 변경 사항은 취소됩니다.

3. 트랜잭션의 예시.

은행 계좌 이체

은행에서 A 계좌에서 B 계좌로 100달러를 이체하는 과정을 생각해 보겠습니다. 이 과정은 여러 단계로 나누어지며, 이들 단계를 하나의 트랜잭션으로 묶습니다.

  • 1. A 계좌에서 100 달러 인출
  • 2. B 계좌에서 100달러 입금

이때 두 작업은 하나의 트랜잭션으로 처리되며, 아래의 두 가지 경우를 고려할 수 있습니다.

  • 정상적인 경우 : 두 단계가 모두 성공하면 트랜잭션이 COMMIT되어 계좌 상태가 갱신됩니다.
  • 실패한 경우 : A 계좌에서 100달러를 인출했지만, B 계좌로 입금하는 과정에서 문제가 발생하면 트랜잭션은 ROLLBACK되어 A 계좌의 상태도 원래대로 되돌아갑니다. 이로 인해 시스템은 일관된 상태를 유지합니다.

트랜잭션 예제(SQL)

BEGIN TRANSACTION;

UPDATE accounts
SET balance = balance - 100
WHERE account_id = 'A';

UPDATE accounts
SET balance = balance + 100
WHERE account_id = 'B';

COMMIT;
  • 위 SQL 예제는 트랜잭션 내에서 두 개의 UPDATE 문이 실행되며, 마지막 COMMIT 명령이 실행되며 트랜잭션이 성공적으로 완료됩니다.
  • 만약 중간에 오류가 발생하면 ROLLBACK을 통해 변경 사항이 취소될 수 있습니다.

4. Java와 Spring에서의 트랜잭션.

Java 애플리케이션에서 트랜잭션은 보통 데이터베이스와 관련된 작업을 처리할 때 사용됩니다.
Spring Framework@Transactional 애너테이션을 통해 트랜잭션을 쉽게 관리할 수 있도록 지원합니다.

예시: @Transactional 사용

@Service
public class BankService {
    
    @Autowired
    private AccountRepository accountRepository;
    
    @Transactional
    public void transferMoney(Long fromAccountId, Long toAccountId, BigDecimal amount) {
        Account fromAccount = accountRepository.findById(fromAccountId).orElseThrow();
        Account toAccount = accountRepository.findById(toAccountId).orElseThrow();
        
        fromAccount.debit(amount);
        toAccount.credit(amount);
        
        accountRepository.save(fromAccount);
        accountRepository.save(toAccount);
    }
}
  • @Transactional
    • 이 메서드는 트랜잭션 내에서 실행되며, 메서드 내에서 오류가 발생할 경우 모든 변경 사항은 ROLLBACK 됩니다.
    • 성공적으로 완료되면 COMMIT되어 데이터베이스에 영구적으로 반영됩니다.

5. 트랜잭션의 중요성.

1. 데이터 무결성 보장.

  • 트랜잭션은 데이터의 무결성을 보장합니다.
  • 트랜잭션 내에서 발생하는 모든 작업은 성공적으로 완료되지 않으면 원래 상태로 되돌리므로, 일관성 없는 데이터가 데이터베이스에 저장되는 것을 방지합니다.

2. 복잡한 비즈니스 로직 처리.

  • 여러 단계로 이루어진 비즈니스 로직, 특히 금융 거래나 주문 처리 같은 중요한 작업에서는 트랜잭션을 사용하여 데이터의 일관성을 유지하고 오류 발생 시 안전하게 롤백할 수 있습니다.

3. 동시성 제어

  • 여러 사용자가 동시에 데이터베이스에 접근할 때 트랜잭션을 통해 동시성 문제를 방지할 수 있습니다.
  • 고립성을 통해 서로 간섭 없이 작업이 처리되도록 보장합니다.

6. 트랜잭션 격리 수준

트랜잭션의 고립성(Isolation) 은 동시에 실행되는 여러 트랜잭션이 서로에게 미치는 영향을 제어하는 수준을 결정합니다.
트랜잭션 격리 수준에는 다음과 같은 단계가 있습니다.

  • 1. READ UNCOMMITED
    • 다른 트랜잭션이 아직 COMMIT되지 않은 데이터를 읽을 수 있습니다.
    • 가장 낮은 격리 수준이며, 일관성 문제가 발생할 수 있습니다.
  • 2. READ COMMITED
    • 다른 트랜잭션이 COMMIT한 데이터만 읽을 수 있습니다.
    • 일반적인 수준의 격리이며, 대부분의 데이터베이스가 기본적으로 이 수준을 사용합니다.
  • 3. REPEATABLE READ
    • 트랜잭션 내에서 동일한 데이터를 여러 번 읽어도 항상 같은 데이터를 읽을 수 있습니다.
    • 읽는 동안 데이터가 변경되지 않습니다.
  • 4. SERIALIZABLE
    • 가장 높은 격리 수준으로, 트랜잭션이 직렬화되어 실행됩니다.
    • 동시성 문제가 없지만 성능에 영향을 미칠 수 있습니다.

7. 요약.

  • 트랜잭션은 데이터베이스의 일련의 작업을 하나의 단위로 처리하며, 모든 작업이 성공하면 COMMIT, 실패하면 ROLLBACK을 통해 데이터의 일관성을 보장합니다.
  • ACID 원칙에 따라 트랜잭션은 원자성, 일관성, 고립성, 지속성을 보장합니다.
  • 트랜잭션은 중요한 비즈니스 로직에서 데이터 무결성을 유지하고 오류를 방지하는 중요한 매커니즘입니다.
  • Java와 Spring에서는 @Transactional 애너테이션을 통해 트랜잭션을 쉽게 관리할 수 있습니다.

4️⃣ 엔티티(Entity)

  • 엔티티(Entity)데이터베이스 또는 애플리케이션의 비즈니스 로직에서 관리해야하는 데이터를 표현하는 객체 또는 클래스입니다.
  • 엔티티는 애플리케이션의 핵심 비즈니스 개념을 나타내며, 주로 데이터베이스의 데이블과 매핑됩니다.

1. 엔티티의 특징.

1. 데이터베이스 테이블과 매핑.

  • 엔티티는 데이터베이스 테이블 레코드(row)와 1:1로 매핑됩니다.
    • 예를 들어, User 엔티티는 데이터베이스의 user 테이블과 매핑되어 사용자를 관리하는 데 사용됩니다.
  • 각 엔티티는 데이터베이스에서 관리되는 실제 데이터를 표현하며, 각 엔티티의 인스턴스는 테이블의 행(row)을 의미합니다.

2. 상태(필드)를 가진 객체.

  • 엔티티는 주로 애플리케이션의 데이터를 나타내는 속성(필드)을 가지고 있습니다.
  • 이 필드는 테이블의 컬럼(Column, 열)에 대응됩니다.

3. 고유한 식별자(Primary Key)

  • 엔티티는 데이터베이스에서 고유하게 식별될 수 있는 식별자(Primary Key) 를 가져야 합니다.
  • 식별자는 각 엔티티 인스턴스를 유일하게 구분하는 값입니다.

4. 영속성(Persistence)

  • 엔티티는 데이터베이스와 같은 영속적인 저장소에 저장되며, 이 저장소에 데이터를 가져오거나 저장할 수 있는 객체입니다.
  • 즉, 엔티티는 데이터베이스에서 지속적으로 관리되고 필요할 때 다시 사용할 수 있습니다.

2. 엔티티의 예시.

1. Java에서의 엔티티.

  • Spring Data JPA나 Hibernate 같은 ORM(Object-Relational Mapping) 프레임워크에서 엔티티는 주로 클래스에 @Entity 애너테이션을 붙여서 정의합니다.

이 클래스는 데이터베이스 테이블과 직접적으로 매핑됩니다.

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

@Entity
public class User {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id; // Primary Key
    
    private String name;
    private String email;
    
    // 기본 생성자
    public User() {}
    
    // Getter and Setter
    public Long getId() {
        return id;
    }
    
    public void setId(Long id) {
        this.id = idl
    }
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name
    }
    
    public String getEmail() {
        return email;
    }
    
    public void setEmail(String email) {
        this.email = email;
    }
}

2. 데이터베이스 테이블과 매핑

User 엔티티 클래스는 다음과 같은 데이터베이스 테이블에 매핑됩니다.

CREATE TABLE users (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255),
    email VARCHAR(255)
)
  • @Entity
    • 이 클래스가 데이터베이스의 엔티티임을 나타냅니다.
    • 이 클래스는 데이터베이스의 테이블과 매핑이됩니다.
  • @Id
    • 이 필드가 엔티티의 고유한 식별자인 Primary Key 임을 나타냅니다.
  • @GeneratedValue
    • 데이터베이스에서 자동으로 생성되는 값임을 지정합니다.
    • GenerationType.IDENTITY는 데이터베이스에서 자동으로 증가하는 ID 값을 사용합니다.

3. 엔티티의 구성 요소.

1. 식별자(Primary Key)

  • 엔티티는 고유한 식별자를 통해 구분됩니다.
    • 예를 들어, User 엔티티의 id 필드는 데이터베이스의 Primary Key에 해당하며, 이를 통해 각 사용자를 고유하게 구분할 수 있습니다.

2. 속성(Attributes)

  • 엔티티는 여러 속성을 가집니다.
  • 속성은 엔티티의 필드로 정의되며, 데이터베이스 테이블의 컬럼에 대응됩니다.
    • 예를 들어 User 엔티티의 nameemail 필드는 사용자 이름과 이메일을 나타내는 속성입니다.

3. 연관관계(Relationships)

  • 엔티티 간에는 연관 관계가 존재할 수 있습니다.
    • 예를 들어, UserOrder라는 두 엔티티가 있을 때, 하나의 사용자가 여러 개의 주문을 가질 수 있습니다.
    • 이러한 관계는 JPA에서 @OneToMany, @ManyToOne, @OneToOne, @ManyToMany 등의 애너테이션으로 정의됩니다.

예를 들어, 사용자와 주문의 관계는 다음과 같이 정의될 수 있습니다.

@OneToMany(mappedBy = "user")
private List<Order> ordersl

4. 상태 및 동작.

  • 엔티티는 데이터베이스의 상태를 반영하며, 비즈니스 로직을 처리하는 데 사용될 수 있습니다.
    • 예를 들어, User 엔티티가 사용자에 대한 상태(활성화 여부 등)를 관리하고, 특정 상태에 따른 로직을 처리할 수 있습니다.

4. 엔티티와 DTO의 차이점.

  • 엔티티(Entity)
    • 엔티티는 데이터베이스 테이블과 매핑된 객체로, 데이터베이스와의 상호작용(저장, 조회, 업데이트 등)에 사용됩니다.
    • 보통 데이터베이스의 필드와 1:1로 매핑되며, 비즈니스 로직을 포함하기도 합니다.
  • DTO(Data Transfer Object)
    • DTO는 주로 계층 간 데이터 전송을 위한 객체로, 데이터베이스와의 직접적인 연관이 없습니다.
    • DTO는 전송에 필요한 필드만 포함하고, 엔티티와는 별도의 구조를 가질 수 있습니다.
    • 이는 주로 클라이언트와 서버 간의 데이터를 주고받기 위해 사용됩니다.

예를 들어, 클라이언트로부터 사용자를 생성하는 요청을 받을 때 DTO를 사용하여 필요한 데이터만 받아오고, 이를 엔티티로 변환하여 데이터베이스에 저장할 수 있습니다.

5. 엔티티의 역할.

1. 데이터베이스와의 상호작용.

  • 엔티티는 데이터베이스와의 상호작용을 위한 매핑 객체로, 애플리케이션이 데이터베이스에서 데이터를 저장, 수정, 삭제, 조회할 수 있도록 합니다.

2. 비즈니스 로직 포함.

  • 엔티티는 단순한 데이터 구조뿐만 아니라, 비즈니스 로직을 포함할 수 있습니다.
    • 예를 들어, User 엔티티는 이메일 형식을 검증하거나 특정 조건에 따라 사용자를 활성화 또는 비활성화하는 로직을 포함할 수 있습니다.

3. 영속성 컨텍스트에서 관리.

  • 엔티티는 JPA와 같은 ORM(Object-Relational Mapping) 프레임워크에서 영속성 컨텍스트에 의해 관리됩니다.
  • 즉, 엔티티의 상태는 트랜잭션 동안 영속성 컨텍스트에 의해 추적되며, 트랜잭션이 완료될 때 해당 상태는 자동으로 데이터베이스에 반영됩니다.

6. 엔티티와 ORM(Object-Relational Mapping)

  • 엔티티는 ORM에서 중요한 역할을 합니다.
  • ORM은 객체 지향 프로그래밍 언어에서 사용하는 객체와 관계형 데이터베이스의 데이터를 매핑해주는 기술입니다.
  • 즉, 엔티티는 ORM에 의해 자동으로 데이터베이스 테이블과 매핑되고, 데이터베이스와의 상호작용을 객체 지향적으로 처리할 수 있도록 도와줍니다.

Sping Data JPA나 Hibernate 같은 ORM 프레임워크를 사용하면, 엔티티를 통해 SQL 쿼리를 작성할 필요 없이 데이터베이스와 상호작용할 수 있습니다.

7. 요약.

  • 엔티티(Entity) 는 애플리케이션의 중요한 비즈니스 객체로, 데이터베이스의 테이블과 매핑되며 데이터를 관리하는 역할을 합니다.
  • 엔티티는 고유한 식별자(Primary Key) 를 통해 데이터베이스에서 유일하게 구분되며, 속성과 연관관계를 가집니다.
  • 엔티티는 비즈니스 로직을 포함할 수 있으며, 데이터베이스와의 상호작용을 객체 지향적으로 처리하기 위한 핵심 요소입니다.
  • ORM 프레임워크를 통해 엔티티는 데이터베이스와 매핑되며, 이를 통해 SQL 쿼리 없이도 데이터를 쉽게 관리 할 수 있습니다.

5️⃣ 비즈니스 로직과 비즈니스 규칙의 차이점.

비즈니스 로직과 비즈니스 규칙은 소프트웨어 개발에서 자주 사용되는 용어이며, 둘 다 애플리케이션의 핵심적인 기능을 정의하지만, 서로 다른 개념입니다.

이 둘의 차이점을 명확히 이해하면 소프트웨어 설계를 더욱 체계적으로 할 수 있습니다.

1. 비즈니스 로직(Business Logic)

비즈니스 로직은 애플리케이션이 어떻게 동작해야 하는지를 정의하는 구현 세부 사항입니다.
비즈니스 로직은 주로 데이터 처리를 포함한 구체적인 작업들을 말하며, 애플리케이션의 기능을 실행하는데 필요한 논리입니다.

예시

  • 사용자로부터 입력을 받아 처리하고, 그 결과를 저장하거나 반환하는 작업.
  • 계좌 이체 기능에서, 특정 계좌에서 돈을 빼고, 다른 계좌에 돈을 넣는 과정에서 수행되는 구체적인 계산과 데이터베이스 업데이트.
  • 재고 관리 시스템에서 제품이 출고되면 재고 수량을 줄이고, 재고가 부족할 경우 경고를 보내는 로직.

특징.

  • 프로세스 중심 : 비즈니스 로직은 시스템 내에서 처리되는 전체 비즈니스 프로세스를 구현합니다.
  • 구현 세부사항 : 어떻게 데이터를 처리하고, 어떤 순서로 작업이 진행되어야 하는지 등 구체적인 방법을 정의합니다.

예시 코드(계좌 이체)

public void transfer(Account fromAccount, Account toAccount, BigDecimal amount) {
    if (fromAccount.getBalnce().compareTo(amount) < 0) {
        throw new InsufficientFundsException("잔액이 부족합니다.");
    }
    
    fromAccount.debit(amount);
    toAccount.credit(amount);
    
    accountRepository(fromAccount);
    accountRepository(toAccount);
}
  • 위 코드에서는 계좌 간의 금액 이체를 처리하는 비즈니스 로직이 구현되어 있습니다.
    • 이 로직은 구체적인 프로세스(잔액 확인, 계좌 차감 및 입금, 데이터 저장)를 다룹니다.

2. 비즈니스 규칙(Business Rule)

비즈니스 규칙은 비즈니스 로직에서 지켜야 할 규칙이나 제약을 의미합니다.
즉, 무엇을 해야 하고 무엇을 하지 말아야 하는지를 정의하는 비즈니스적 요구 사항입니다.
비즈니스 규칙은 회사의 운영 정책, 법적 규제, 계약 조건, 업계 표준 등에서 도출된 규정들로, 애플리케이션의 도메인(업무)에서 어떤 작업이 허용되고 금지되는지 결정합니다.

예시.

  • 계좌 이체 시 잔고가 부족하면 이체가 불가능합니다.
  • 특정 시간대에만 주문을 받을 수 있습니다.
  • 18세 미만은 성인용 제품을 구매할 수 없습니다.

특징.

  • 정책 중심
    • 비즈니스 규칙은 특정 비즈니스 상황에서 허용되는 동작과 금지되는 동작을 정의합니다.
  • 비즈니스 요구 사항
    • 비즈니스 규칙은 도메인 전문가나 비즈니스 팀이 결정하며, 시스템 설계자가 아닌 비즈니스 자체에서 도출된 요구 사항입니다.
  • 독립적
    • 비즈니스 규칙은 비즈니스 로직과는 독립적으로 존재할 수 있으며, 기술적인 구현 방법과는 관계없이 정의됩니다.

예시 코드(잔액 부족 확인)

public class Account {
    public boolean hasSufficientFunds(BigDecimal amount) {
        return this.balance.compareTo(amount) >= 0;
    }
}
  • 이 코드에서는 비즈니스 규칙인 “잔액이 부족하면 이체를 할 수 없다”는 규칙을 구현한 메서드를 정의했습니다.
    • 비즈니스 로직에서 이 규칙을 호출하여 실제로 잔액이 부족한지 확인하고, 필요한 조치를 취합니다.

3. 차이점 요약.

구분 비즈니스 로직(Business Logic) 비즈니스 규칙(Business Rule)
정의 애플리케이션이 어떻게 동작해야 하는지에 대한 구현. 시스템이 지켜야 할 비즈니스적 제약과 요구 사항.
포커스 기능과 프로세스의 실행 방식. 비즈니스 요구사항을 준수하기 위한 규정 및 제약.
주체 주로 개발자나 시스템 설계자가 구현. 도메인 전문가나 비즈니스 담당자에 의해 정의.
예시 데이터 저장, 계산 처리, 트랜잭션 관리 등 나이 제한, 거래 가능 시간, 신용 한도 초과 등
기술적 관점 기술적, 구현적 측면에서 다름. 기술 구현과 독립적, 비즈니스적 규칙을 나타냄.
영향 애플리케이션 동작을 정의. 동작을 제약하거나 허용함.

4. 비즈니스 로직과 비즈니스 규칙의 관계.

  • 비즈니스 규칙은 비즈니스 로직을 통해 실현됩니다.
    • 즉, 비즈니스 로직이 수행될 때 비즈니스 규칙이 적용되어야 합니다.
  • 비즈니스 로직은 시스템의 동작 방식을 정의하며, 비즈니스 규칙은 해당 로직이 동작할 때 지켜야 하는 제약과 조건을 결정합니다.
  • 비즈니스 규칙은 고정된 정책이나 규정이지만, 비즈니스 로직은 이를 적용하여 다양한 프로세스를 실행하는 구체적인 방법입니다.

비즈니스 로직과 규칙의 예시

  • 비즈니스 규칙 : 계좌 잔액이 부족하면 인출할 수 없다
  • 비즈니스 로작 : 계좌 인출 과정에서 잔액 확인, 금액 인출, 기록 저장 등의 구체적인 절차를 처리.

5. 요약.

  • 비즈니스 로직은 애플리케이션에서 어떻게 처리할지를 다루는 구체적인 작업이며, 시스템의 기능을 정의합니다.
  • 비즈니스 규칙은 비즈니스 운영에서 지켜야 할 규정과 제약을 의미하며, 비즈니스의 요구 사항을 시스템에 반영하기 위한 규칙입니다.
  • 비즈니스 로직은 비즈니스 규칙을 준수하면서 시스템이 어떻게 동작해야 하는지를 구현하는 방식으로, 둘은 상호 보완적인 관계를 가집니다.