00. Kick-Off

얼음 깨기

[CyberMES 2027]

  • 2027년의 MES 아키텍처는 어떻게 변할까요?

  • 사이버 펑크의 시대가 과연 올까요?

내 손안의 마이크로서비스

image1 image2

스터디 소개

[내용]cd

  • 스터디 모토

  • 스터디 미션

  • 스터디 규칙

  • 멤버 소개

스터디 모토

  • 무엇을 얻을것인지 생각

  • 자랑하고 인정받고 칭찬받는 놀이터

    • ~라는 최신 정보가 있어요 - 엄지척

스터디 미션

  • 메인 미션: 책 완독, 관심 내용 발표 1회이상

  • 그 이외에는 자유

  • 다양한 도전과제와 즐길거리 제공

    • 서브 퀘스트: MSA 토이 프로젝트 만들어서 호스팅하기

    • 사이드 퀘: AWS/Azure에서 MSA 서비스 호스팅, 다른 모던 언어 배워보기, DevOps 배우기, AWS 자격증, 라즈베리파이로 개인 클러스터 만들기, 모바일 앱 만들어 플레이스토에 배포하기 등

겁먹지 마세요

  • 책 내용이 어렵지만 다 이해할 필요 없어요.

    • 책을 “완독” 하는게 목적이지 “완성”하는게 목적이 아닙니다.

  • 메인 퀘스트가 어려우면 난이도를 낮추세요.

    • 챕터에서 알고싶은 범위를 한정하거나, 이해할 챕터 분량을 한정하기

  • 메인 퀘스트가 어려우면 서브/사이드 퀘스트에서 재미를 찾으세요!

  • 이해 안가는 내용은 슬랙 / 컨플루언스에 언제든 물어보세요.

추천 미션 예:

다음중 하나를 해보고 스샷을 공유해주세요, 추천 수에 따라서 스벅 쿠폰을 보내드립니다(?)

  • 마음에 드는 언어 하나 골라서 도메인 모델링 예제 구현 해보기

  • 파이썬 도커 개발 환경에 JupyterLab 셋팅해보기

  • 클라우드 플랫폼 (AWS, Azure, 또는 GCP) 가입해서 가상머신에 앱 하나 띄워보기

  • 책에서 감명깊게 본 부분 캡쳐해서 감상평 올리기~

교재 선정 이유

https://github.com/cosmicpython/book

  • 거의 유일 무이한 파이썬 기반 아키텍처 북

  • 실천적인 접근 방법: 이론만큼 구현에도 중점

  • 최신 교재 / 최신 파이썬 기술 포함

  • MSA를 맹신하지 않음.

  • 엄청난 아마존 평점

스터디 규칙

  • 공휴일 / 연휴 제외 매주 모이는 것을 원칙으로 합니다.

  • 매주 내드리는 메인 미션은 반드시 완수하셔야 합니다.

  • 메인 미션은. 정해진 분량의 교재 범위를 읽어오시고

  • 지난번 모임에서 읽은 챕터의 테스트 코드를 완성시켜오시는 것입니다.

  • 스터디를 마치기 전까지 최소 1번 이상 발표를 하셔야 합니다

토론

[내용]

  • 왜 마이크로서비스가 대세일까요?

  • 왜 파이썬으로 하나요?

  • 스터디 운영방법?

왜 마이크로서비스가 대세일까요?

  • 마이크로서비스가 소프트웨어 복잡성을 해결하는 현재까지 가장 진보된 방법이기 때문에

  • 거대한 모놀리식 서비스를 세부레벨로 찢어서 부서간의 사일로 해결

  • 그럼에도 개별 서비스들의 영향의 컨테이너 레벨로 안전하게 격리하고 서비스 메시를 통해 스케일 아웃 가능

  • SOA처럼 헤비한 프레임워크를필요로 하지 않아 간단하게 시작해볼 수 있음

  • 마이크로서비스 운영 기술을 통해 엔터프라이즈 레벨로 확장이 용이

왜 파이썬으로 하나요?

  • 가장 인기있는 언어

  • 가장 빨리 발전하고 있는 언어 중 하나

  • 오너십과 파이썬 커뮤니티니의 건전성

    • 리눅스와 비슷? PEP 읽어보면 귀도 반 로섬이 거의 항상 참여

효과적인 스터디 운영방법은?

  • 무엇을 공부하게 되나요?

  • 너무 어렵지는 않을까요?

  • 재미있게 열심히 할 수 있을까요?

  • 회비 기반으로 동기부여하기

    • 총무가 필요합니다. (매 주 5000원씩 회비를 걷습니다)

    • 엄지척을 많이 받은 발표자에게 상품 쿠폰을 제공합니다.

책 둘러보기

Whenever we introduce an architectural pattern in this book, we’ll always ask,

“What do we get for this? And what does it cost us?”

Introduction

  • Why Do Our Designs Go Wrong?

  • Encapsulation and Abstractions

  • Layering

  • The Dependency Inversion Principle

  • A Place for All Our Business Logic: The Domain Model

I. Building an Architecture to Support Domain Modeling

1. Domain Modeling

  • What Is a Domain Model?

  • Exploring the Domain Language

  • Unit Testing Domain Models

  • Not Everything Has to Be an Object: A Domain Service Function

2. Repository Pattern

  • Persisting Our Domain Model

  • Some Pseudocode: What Are We Going to Need?

  • Applying the DIP to Data Access

  • Reminder: Our Model

  • Introducing the Repository Pattern

  • Building a Fake Repository for Tests Is Now Trivial!

  • What Is a Port and What Is an Adapter, in Python?

3. A Brief Interlude: On Coupling and Abstractions

  • Abstracting State Aids Testability

  • Choosing the Right Abstraction(s)

  • Implementing Our Chosen Abstractions

4. Our First Use Case: Flask API and Service Layer

  • Connecting Our Application to the Real World

  • A First End-to-End Test

  • The Straightforward Implementation

  • Error Conditions That Require Database Checks

  • Introducing a Service Layer, and Using FakeRepository to Unit Test It

  • Why Is Everything Called a Service?

  • Putting Things in Folders to See Where It All Belongs

5. TDD in High Gear and Low Gear

  • How Is Our Test Pyramid Looking?

  • Should Domain Layer Tests Move to the Service Layer?

  • On Deciding What Kind of Tests to Write

  • High and Low Gear

  • Fully Decoupling the Service-Layer Tests from the Domain

  • Carrying the Improvement Through to the E2E Tests

6. Unit of Work Pattern

  • The Unit of Work Collaborates with the Repository

  • Test-Driving a UoW with Integration Tests

  • Unit of Work and Its Context Manager

  • Using the UoW in the Service Layer

  • Explicit Tests for Commit/Rollback Behavior

  • Explicit Versus Implicit Commits

  • Examples: Using UoW to Group Multiple Operations into an Atomic Unit

  • Tidying Up the Integration Tests

7. Aggregates and Consistency Boundaries

  • Why Not Just Run Everything in a Spreadsheet?

  • Invariants, Constraints, and Consistency

  • What Is an Aggregate?

  • Choosing an Aggregate

  • One Aggregate = One Repository

  • What About Performance?

  • Optimistic Concurrency with Version Numbers

  • Testing for Our Data Integrity Rules

II. Event-Driven Architecture

8. Events and the Message Bus

  • Avoiding Making a Mess

  • Single Responsibility Principle

  • All Aboard the Message Bus!

  • Option 1: The Service Layer Takes Events from the Model and Puts Them on the Message Bus

  • Option 2: The Service Layer Raises Its Own Events

  • Option 3: The UoW Publishes Events to the Message Bus

9. Going to Town on the Message Bus

  • A New Requirement Leads Us to a New Architecture

  • Refactoring Service Functions to Message Handlers

  • Implementing Our New Requirement

  • Test-Driving a New Handler

  • Optionally: Unit Testing Event Handlers in Isolation with a Fake Message Bus

10. Commands and Command Handler

  • Commands and Events

  • Differences in Exception Handling

  • Discussion: Events, Commands, and Error Handling

  • Recovering from Errors Synchronously

11. Event-Driven Architecture: Using Events to Integrate Microservices

  • Distributed Ball of Mud, and Thinking in Nouns

  • Error Handling in Distributed Systems

  • The Alternative: Temporal Decoupling Using Asynchronous Messaging

  • Using a Redis Pub/Sub Channel for Integration

  • Test-Driving It All Using an End-to-End Test

  • Internal Versus External Events

12. Command-Query Responsibility Segregation (CQRS)

  • Domain Models Are for Writing

  • Most Users Aren’t Going to Buy Your Furniture

  • Post/Redirect/Get and CQS

  • Hold On to Your Lunch, Folks

  • Testing CQRS Views

  • “Obvious” Alternative 1: Using the Existing Repository

  • Your Domain Model Is Not Optimized for Read Operations

  • “Obvious” Alternative 2: Using the ORM

  • SELECT N+1 and Other Performance Considerations

  • Time to Completely Jump the Shark

  • Changing Our Read Model Implementation Is Easy

13. Dependency Injection (and Bootstrapping)

  • Implicit Versus Explicit Dependencies

  • Aren’t Explicit Dependencies Totally Weird and Java-y?

  • Preparing Handlers: Manual DI with Closures and Partials

  • An Alternative Using Classes

  • A Bootstrap Script

  • Message Bus Is Given Handlers at Runtime

  • Using Bootstrap in Our Entrypoints

  • Initializing DI in Our Tests

  • Building an Adapter “Properly”: A Worked Example

Epilogue

  • What Now?

  • How Do I Get There from Here?

  • Separating Entangled Responsibilities

  • Identifying Aggregates and Bounded Contexts

  • An Event-Driven Approach to Go to Microservices via Strangler Pattern

  • Convincing Your Stakeholders to Try Something New

  • Questions Our Tech Reviewers Asked That We Couldn’t Work into Prose

  • Footguns

  • More Required Reading

Appendicies

    1. Summary Diagram and Table

    1. A Template Project Structure

    1. Swapping Out the Infrastructure: Do Everything with CSVs

    1. Repository and Unit of Work Patterns with Django

    1. Validation

참고: 프로그래밍 언어 랭킹

PYPL 2020

  1. Python (30.34% / +1.2%) – 더 할말이?

  2. Java (17.23% / -1.7%)

  3. JavaScript (8.65% / +0.6%) – [TypeScript]: 왕위를 계승중입니다…

  4. C# (6.44% / -0.8%) – .NET Framwork의 최강자

  5. C/C++ / 6.11% / +0.1%)

  6. PHP (5.88% / -0.3%)

  7. R (3.84% / +0.1%) – 한때 유일하게 쓸만한 통계/데이터 과학 언어,Jupyter의 3대장

  8. Objective-C (3.75% / +1.2%)

  9. Swift (2.17% / -0.3%)

  10. Matlab (1.77% / -0.0%)

  11. TypeScript (1.62% / -0.2%)

  12. Go (1.52% / +0.3%) – 마이크로서비스 트렌드의 대세

  13. Kotlin (1.44% / -0.2%) – JVM 기반 언어중 최고 대세

  14. Ruby (1.28% / -0.1%)

  15. Rust (1.12% / +0.5%) – 마이크로서비스 트렌드의 또다른 대세언어, 함수형 언어의 적자

  16. VBA (1.05% / -0.3%)

  17. Scala (0.97% / -0.1%) – Kotlin에게 인기 빼앗기는 중…

  18. Visual Basic (0.67% / -0.3%)

  19. Ada (0.61% / +0.3%)

  20. Dart (0.58% / +0.2%) – Flutter 프레임웍으로 인기 급상승

  21. Lua (0.55% / +0.2%)

  22. Perl (0.46% / -0.1%)

  23. Groovy (0.43% / -0.0%) – 최고 Cool한 JVM 언어였지만.. Kotlin/Scala에 인기 다뺏김 Gradle로 연명중

  24. Abap (0.41% / -0.1%)

  25. Julia (0.33% / +0.1%) – Data Scientist 들에게 사랑받는 언어,Jupyter의 3대장

  26. Haskell (0.27% / -0.0%)

  27. Cobol (0.26% / -0.1%)

  28. Delphi (0.26% / +0.0%)

3분 DDD

도메인 모델링이란

Domain modeling

  • The part of your code that is closest to the business.

  • The most likely to change, and the place where you deliver the most value to the business.

  • Need to make it easy to understand and modify.

Distinguish entities from value objects

Value Objects - Defined by its attributes. - Usually best implemented as an immutable type. - If you change an attribute on a Value Object, it represents a different object.

Entities - Even though an entity has attributes that may vary over time, it will still be the same entity. - Important to define what does uniquely identify an entity - usually some sort of name or reference field).

Not everything has to be an object

  • The “verbs” in your code be functions.

    • e.g) FooManager, BarBuilder, BazFactory

    • vs.

    • manage_foo(), build_bar(), get_baz()

This is the time to apply your best OO design principles

  • Revisit the SOLID principles

  • All the other good heuristics like “has a versus is-a,” “prefer composition over inheritance,” and so on.

You’ll also want to think about consistency boundaries and aggregates

But that’s a topic for [chapter_07_aggregate].

Value Object in Python

[10]:
from dataclasses import dataclass

@dataclass(frozen=True)
class User:
    name: str
    age: int

user1 = User('John', 16)
user2 = User(age=16, name='John')

user1 == user2 # True
[10]:
True

참고: 모던 프로그래밍 언어에서 Value Object 구현 방법

public record User(String Name, int Age);

var user1 = new User("John", 16);
var user2 = new User("John", 16);
user1 == user2

public record User2 {
    public String Name { get; init; }
    public int Age { get; init; }
};

var user1 = new User2 { Name="Love", Age=17 };
var user2 = new User2 { Age=17, Name="Love" };
user1 == user2
// `ValueObject` 구현 방법은 별도 노트북을 참조하세요.
interface UserProps {
    name: String
    age: number
}

class User extends ValueObject<UserProps> {
  constructor(props) { super(props) }
}

const user1 = new User({name: 'John', age: 16})
const user2 = new User({age: 16, name: 'John'})

user1 === user2 // false
user1.equals(user2) // true
type User struct {
    name string
    age  int
}

user1 := User { "John", 16 }
user2 := User { "John", 16 }

user1 == user2 // true

// 당황: Go는 Immuable 속성을 지원하지 않아서 동적으로 속성을 변경 가능.

user1.name = "Test"
user1 == user2 // false
data class User(val name: String, val age: Int)

val user1 = User("John", 10)
val user2 = User("John", 10)

user1 == user2 // true
##[derive(PartialEq, Eq)]
struct User { name: String, age: u16 }

let user1 = User { name: String::from("John"), age: 16 };
let user2 = User { name: String::from("John"), age: 16 };

user1 == user2 // true
import groovy.transform.Immutable

@Immutable class User {
    String name
    int age
}

final user1 = new User('John', 16)
final user2 = new User([age: 16, name: 'John'])

user1 == user2 // true
import Base.@kwdef

@kwdef struct User
    name::String
    age::UInt8
end

user1 = User("John", 16)
user2 = User(age=16, name="John")

user1 == user2 # true
data User = User
  { name :: String,
    age  :: Int
  } deriving (Eq, Show)

user1 = User { name = "John", age = 16 }
user2 = User { age = 16, name = "John" }
user1 == user2 -- True

결론

  • 3개월 안에 책을 다 읽을 겁니다

  • 3개월 동안 MSA 토이 프로젝트를 완성하고 발표를 하게 될 거에요.

  • 스터디는 정말 재밌게 할 수 있을 겁니다!

  • 특별한 일 없으면 매 주 오프라인/온라인 교대로 만날거에요.

  • 다음주에 또 만나요 :D