단방향 의존성을 갖고 있는데 이는 자신의 Layer 보다 바로 아래의 레이어에만 의존한다는 것입니다. 그러므로 Presentation Layer는 Business Layer에게만 Business Layer는 Persistence Layer에게만 의존합니다. 따라서 두 단계를 건너 띈 레이어에게 영향을 주지 않고 상위 레이와 전혀 별개로 동작한다는 특징이 있습니다.
Presentation Layer(레이어)는 시스템을 사용하는 Client가 시스템과 직접적으로 연결되는 부분이다.
가장 표면에 있는 레이어로 엔드포인트를 구성하는 역할을 한다.
즉, API 엔드포인트를 정의하고 전송된
HTTP request를 읽어오는 Logic(로직)을 구현
그 이후의 역할은 Business Layer로 넘겨주게 됩니다.
Flask에서는 보통 view라는 Directory에 정의
역할은 동일하며 Flask의 route decorator(데코레이터)를 사용해 EndPoint를 등록
로그인(sign-in)과 관련된 엔드포인트를 구성한다고 했을 때, 다음과 같은 코드로 생성된다.
# app_name/user/user_view.py
def create_endpoints(app, service):
user_service = service.user_service
@app.route("/sign-up", methods=['POST'])
def sign_up():
new_user = request.json
new_user_id = user_service.create_new_user(new_user)
new_user = user_service.get_user(new_user_id)
return jsonify(new_user)
중간에 user_service의 create_new_user function을 사용하는데 바로 이 부분이 Presentation Layer가 Business Layer를 의존하는것
user를 생성하는 역할은 별도 정의된 함수를 통해 진행하는 것이다.
실제 시스템에서 구현되는 Validation(유효성) 검사등이 이루어 진다.
위 예제에 이어서 새로운 유저를 생성하는 로직
#app_name/service/user_service.py
class UserService:
def __init__(self, user_dao):
self.user_dao = user_dao
def create_new_user(self, new_user):
new_user['password'] = bcrypt.hashpw(
new_user['password'].encode('UTF-8'),
bcyrpt.gensalt())
new_user_id = self.user_dao.insert_user(new_user)
return new_user_id
위에서 호출 됐던 create_new_user라는 함수가 정의되고 사용되고있다. 여기서 전혀 상위 레이어에 대한 의존성은 없으며 단방향으로 아래에 있는 Persistance Layer가 호출 되고 있습니다.(user_dao 부분)
DataBase와 직접적으로 연결되는 로직이 구현된다.
Data의 CRUD(CREATE, READ, UPDATE, DELETE)가 실제적으로 이루어지는 곳
Flask에서는 model이라는 디렉토리에 생성.
service와 마찬가지로 각 엔드포인트에 맞게 두 개로 나눠 주면 좋다.
파일 이름은 조금 전에 보았듯이 DAO(Database Access Object)
참고할 점은 python에서 mysql을 연동하는 모듈이 mysql-connector-python과 pymysql이 있는데 여기서는 pymysql를 사용하도록 하겠습니다. 아래는 user_dao.py의 코드 가운데 일부
#app_name/model/user_dao.py
class UserDao:
def __init__(self, database):
self.db = database
def insert_user(self, user):
return self.db.execute(text("""
INSERT INTO users (
name,
email,
profile,
hashed_password
) VALUES (
:name,
:email,
:profile,
:password
)
"""), user).lastrowid