Image_Us-폴더 아키텍쳐

codakcodak·2023년 2월 27일
0

ImageUs

목록 보기
2/17
post-thumbnail

1.back_server 폴더 구조

├── Dockerfile
├── README.md
├── access.log
├── app.py
├── auth
│   ├── __init__.py
│   └── user_auth.py
├── config.py
├── managements
│   ├── memory_history
│   ├── memory_monitor.py
│   └── user_generate.py
├── model
│   ├── __init__.py
│   ├── image_model.py
│   ├── room_model.py
│   └── user_model.py
├── requirements.txt
├── service
│   ├── __init__.py
│   ├── image_service.py
│   ├── room_service.py
│   └── user_service.py
├── templates
│   ├── email_auth.html
│   └── search.html
├── test
│   ├── api_performance.py
│   ├── models.py
│   ├── test_model.py
│   ├── test_service.py
│   └── test_view.py
├── test_images
│   ├── sample_image.JPG
│   └── sample_image2.JPG
├── tool
│   ├── __init__.py
│   ├── api.py
│   └── tools.py
└── view
    ├── __init__.py
    ├── image_router.py
    ├── oauth_router.py
    ├── room_router.py
    └── user_router.py
  • app.py - 메인 어플리케이션 파일

  • access.log - 로깅 파일(gunicorn실행시 생성)

  • config.py - 사용자의 기밀 사항이나 민감한 키값들을 저장해 놓는 환경변수

  • Dockerfile - 도커의 빌드 서술 파일

  • auth - 사용자의 인증 관련 파일

  • gitignore - git에서 무시할 파일 이름 저장

  • model - 데이터베이스와 직접적으로 통신

  • service - model을 포함하는 상위 단계이고 모델로 불러온 데이터들을 로직처리하여 실제 서비스를 제공

  • view - service를 포함하는 상위 단계이고 여러 종류의 api들을 라우팅

  • test - 각종 테스트 코드

  • tool - 사용자 정의 함수 또는 클래스를 저장

  • template - html로 내보낼 양식 저장

  • requirements - app을 실행시키기 위한 패키지 목록

  • managements - 메모리 모니터링 및 샘플 데이터 생성 등 관리를 위한 툴 파일

2.상세사항

  • app.py (전체 코드)

    class Services:
        pass
    
    def create_app(test_config=None):
    
        app=Flask(__name__)
    
        CORS(app)
    
        api=Api(app,title='Image_Us back-server api docs',doc='/api-docs')
    
        if test_config is None:
            app.config.from_pyfile("config.py")
        else:
            app.config.update(test_config)
    
        database=create_engine(app.config['DB_URL'],encoding='utf-8',pool_recycle=app.config['POOL_RECYCLE'],pool_size=app.config['POOL_SIZE'],max_overflow=app.config['MAX_OVERFLOW'])
        print("mysql 데이터베이스 연결 성공")
        es=Elasticsearch(hosts=app.config['ELASTIC_URL'])
        print("elastic 데이터베이스 연결 성공")
    
        @app.before_request
        def block_method():
            if 'x-real-ip' in request.headers:
                ip=request.headers['x-real-ip']
            else:
                ip=request.environ.get('REMOTE_ADDR')
            print("Current IP Address:",ip,flush=True)
            print("Current Process:",os.getpid(),flush=True)
    
            splited_ip=ip.split('.')
            ip_range=splited_ip[0]+'.'+splited_ip[1]
    
            if ip not in app.config['GOOD_IP_LIST'] and ip_range not in app.config['GOOD_IP_RANGE']:
                abort(403)
    
        @api.route("/search")
        class search_user(Resource):
            def get(self):
                headers = {'Content-Type': 'text/html'}
                return make_response(render_template('index.html'),200,
                                                  headers)
    
        @api.route("/ping")
        class ping(Resource):
            def get(self):
                '''back 작동 테스트를 위한 api입니다.'''
                return make_response("pong",200)
    
        user_dao=UserDao(database)
        image_dao=ImageDao(database)
        room_dao=RoomDao(database)
    
        services=Services
    
        services.user_service=UserService(user_dao,app.config)
        services.image_service=ImageService(image_dao,app.config)
        services.room_service=RoomService(room_dao,app.config)
    
        oauth_router(api,services,app.config)
        user_router(api,services,app.config,es)
        room_router(api,services)
        image_router(api,services)
    
        return app
    app=create_app()
  • 스웨거 적용을 위한 api클래스 생성

api=Api(app,title='Image_Us back-server api docs',doc='/api-docs')
  • 개발 단계별 분리된 환경변수 적용
    if test_config is None:
        app.config.from_pyfile("config.py")
    else:
        app.config.update(test_config)
  • 다양한 데이터 베이스 엔진 생성 및 확인
database=create_engine(app.config['DB_URL'],encoding='utf-8',pool_recycle=app.config['POOL_RECYCLE'],pool_size=app.config['POOL_SIZE'],max_overflow=app.config['MAX_OVERFLOW'])
print("mysql 데이터베이스 연결 성공")
es=Elasticsearch(hosts=app.config['ELASTIC_URL'])
print("elastic 데이터베이스 연결 성공")
  • app의 정상 작동을 위한 테스트 라우트
@api.route("/ping")
class ping(Resource):
    def get(self):
        '''back 작동 테스트를 위한 api입니다.'''
        return make_response("pong",200)
  • model,service,router에서 필요한 클래스를 포함하여 최종 route 생성
  user_dao=UserDao(database)
    image_dao=ImageDao(database)
    room_dao=RoomDao(database)
    
    services=Services

    services.user_service=UserService(user_dao,app.config)
    services.image_service=ImageService(image_dao,app.config)
    services.room_service=RoomService(room_dao,app.config)

    oauth_router(api,services,app.config)
    user_router(api,services,app.config,es)
    room_router(api,services)
    image_router(api,services)
  • config.py
db={
    "user":"codakcodak",
    "password":"test",
    "host":"localhost",
    "port":3306,
    "database":"imageus_back"
}

test_db={
    'user':'codakcodak_test',
    'password':'test',
    'host':'localhost',
    'port':3306,
    'database':'imageus_back_test'
}

JWT_SECRET_KEY="codakcodak"
DB_URL=f"mysql+mysqlconnector://{db['user']}:{db['password']}@{db['host']}:{db['port']}/{db['database']}?charset=utf8"

test_config={
    'DB_URL':f"mysql+mysqlconnector://{test_db['user']}:{test_db['password']}@{test_db['host']}:{test_db['port']}/{test_db['database']}?charset=utf8",
    'JWT_SECRET_KEY':"codakcodak"
}

*배포 단계의 db와 개발 단계의 test_db로 환경변수를 나누어 저장

  • .gitignore
config.py	#환경변수파일
wsgi.py		#소켓파일
error.log	#로그파일

*민감한 파일들을 명시하여 git 상에 무시하고 업로드

  • model

*user,room,image의 3개의 모델로 분리

  • service

*user,room,image의 3개의 서비스로 분리

  • view

*oauth,user,room,image의 3개의 route로 분리

  • test

*model,service,view의 계층별 테스트 코드 분리 및 models에는 세 개의 테스크 코드에서 공통적으로 쓸 모델 저장

  • tool

*사용자 정의 상태코드 및 스웨거의 모델을 생성하는 클래스와 각종 사용자 정의 함수 저장

  • template

*이메일 인증 시 보내는 양식 및 각종 html 양식 저장

  • requirements
...
Flask==2.2.2
Flask-BasicAuth==0.2.0
Flask-Cors==3.0.10
flask-restx==1.0.3
Flask-Script==2.0.5
Flask-Twisted==0.1.2
Flask-WTF==1.0.1
gevent==22.10.2
...

*pip 명령어를 통한 app에 쓰인 패키지를 저장

3.장점

1.독립적인 계층구조
view는 service를 포함하고 service는 model을 포함하기에
view를 수정해도 serviced에는 영향이 가지 않는다.
->새로운 기능 및 서비스 생성을 유연하고 빠르게 할 수 있다.

2.계층구조 단의 테스트코드
model,service,view의 층으로 나누어 각각의 테스트 코드를 작성하여 탄탄한 서비스 제공이 가능하다.
->model의 코드 수정이 이루어 졌을 때 service 또는 view에 영향이 가는지를 빠르게 파악할 수 있어 안정적인 서비스 개선이 가능하다.

3.개발 과정별 환경변수 분리
새롭게 생성한 app클래스에 원하는 개발과정 이름을 인자로 넣으면 config 파일에서 매칭되는 변수들을 불러온다.
->각각의 개발 및 배포 과정에서의 필요한 변수들을 쉽게 호출 및 적용하여 개발 환경을 유연하게 변경할 수 있다.

profile
숲을 보는 코더

0개의 댓글