해당 게시물은 깔끔한 파이썬 탄탄한 백엔드(송은우 저)의 내용 + pysql을 구글링하여 정리한 것이다. 아래 내용을 바탕으로 생각했을 때, flask 초기세팅 작업 순서는 다음대로 하면 될 것 같다.
Layered architecture pattern, multi-tier architecture pattern이라고도 불린다. 코드를 논리적인 부분 혹은 역할에 따라 독립되 모듈로 나누어서 구성하는 패턴이다.
각 모듈은 서로 의존도에 따라 층층이 쌓듯이 연결되어 전체 시스템을 구현한다. 시스템마다 경우가 다르지만 보통 3개의 레이어가 존재한다.
시스템 사용자, 클라이언트 시스템과 직접 연결되는 부분. 웹사이트에서는 UI에 해당하고 백엔드는 엔드포인트 부분
에 해당한다. 여기에서는 두 가지 로직을 구현한다.
비즈니스 로직을 구현하는 부분이다. 시스템이 구현하는 로직
을 이 레이어에서 구현한다. 예를 들어 사용자가 전송하는 메시지가 300자를 넘을 경우, 이를 확인해 초과할 경우 거부하는 로직을 짜는 곳이다.
데이터베이스와 관련된 로직을 구현하는 부분이다. business layer에서 필요한 데이터 생성, 수정, 읽기를 처리해 데이터베이스에서 데이터를 저장, 수정, 읽어들이기
를 하는 역할을 한다.
presentation layer > business layer > persistence layer 방향으로 의존한다. 그리고 반대 방향은 완전히 독립적이다.
즉, persistence layer는 business, presentaion에 독립적이고 business는 presentation에 독립적이다.
각 레이어의 역할이 명확하다. presentaion layer는 비즈니스 로직을 전혀 구현하지 않고 business layer의 코드를 호출해서 사용해야 한다. business layer도 데이터베이스 처리를 하기 위해 persistence layer의 코드를 사용한다.
장점은
단점은... 초보자인 나로서는 역할 별로 파일이 너무 분산되어 있어서 한 번에 이해하기 어렵고 변수 관리하는 것이 빡세다 😟
api
|- view : presentation layer - endpoint 정의, request 받기
|- service : business layer - 로직 구현
|- model : persistence layer - 데이터베이스 접속
|- app.py : 앱을 실행해 모든 레이어의 변수들을 연결해주는 기능
test endpoint를 하나 만들어 보자. 테이블은 아래와 같이 생겼다. id는 auto_increment 설정이 되어 있는 pk여서 user column만 post해주면 되는 상황이다.
mysql> select * from seller_keys;
+----+-------+
| id | user |
+----+-------+
| 5 | yeeun |
| 6 | yeeun |
| 8 | yeeun |
+----+-------+
view는 service에 의존적이기 때문에 아래 코드에서 create_endpoint 인자 중 app은 app.py에서 정의한 Flask객체app = Flask(__name__)
이고, services는 service의 user_serive에서 받을 로직 부분이다. (변수가 services.user_service인 이유는 app.py에서 Service 객체의 이름을 정의해주었기 때문이다)
하는 일은
from flask import request, jsonify
from model.user_dao import UserDao
from service.user_service import UserService
def create_endpoints(app, services):
user_service = services.user_service
@app.route("/test", methods=['POST'])
def sign_up():
try:
user = request.json
user = user_service.create_new_user(user)
return jsonify({'message':'ok'}), 200
except Exception as e :
return {'error': str(e)}
로직을 담당하는 곳. 로직을 크게 나누어 클래스로 만든다. 예를 들어 내가 만들 서비스가 크게 user, product로 구분된다면 그와 관련된 클래스를 생성해 관련 기능을 모두 함수로 만드는 식이다.
service는 model에 의존적이기 때문에 함수의 파라미터로 model의 user_dao를 넣어준다.
from model.user_dao import UserDao
class UserService:
def __init__(self, user_dao, config):
self.user_dao = user_dao
self.config = config
def create_new_user(self, new_user):
user = self.user_dao.insert_user(new_user)
return user
dabatabse는 pymysql을 통해 데이터베이스에 직접 접속해서, 원하는 값을 입력하거나 찾아서 리턴하는 방식으로 만들어진다.
import json
import pymysql
class UserDao:
def __init__(self, database):
self.db = database
def insert_user(self, user):
cursor = self.db.cursor()
sql = """
insert into seller_keys(
user
) values (
%s
)
"""
cursor.execute(sql, (user['user']))
self.db.commit()
self.db.close()
각 레이어를 이어주는 역할을 한다. 레이어의 클래스나 모듈을 임포트해서 연결시켜주고, Flask 애플리케이션을 생성해주는 역할을 한다.
import pymysql
from flask import Flask
from model.user_dao import UserDao
from service.user_service import UserService
from view import create_endpoints
class Services:
pass
def create_app(test_config = None):
app = Flask(__name__)
app.debug = True
if test_config is None:
app.config.from_pyfile("config.py")
else:
app.config.update(test_config)
database = pymysql.connect(host='localhost',
user='root',
password='',
db='brandi',
charset='utf8'
)
user_dao = UserDao(database)
services = Services
services.user_service = UserService(user_dao, app.config)
user_service = UserService(user_dao, app.config)
create_endpoints(app, services)
return app
정리하셨었군요 예은님~ ㅋㅋ