3. 코, 코, 코딩을 했다!

김근호·2021년 7월 14일
0

2021년 7월 14일 기준

프로젝트를 앞쪽부터 돌아보면 다음과 같은 구조로 되어 있다.
만들어진, 만들어 나갈 결과물은 다음과 같다.

https://ans.heradee.com/sample (스리슬쩍)


1. html, css, js

이 부분은 내가 담당한 부분은 아니다. (Ralphrio님이 FE를 맡기 때문)
css 부분은 거의 관여한 부분이 없다. 개인적으로 css는 너무하다고 생각한다. 그냥 너무해

1-1. html (Jinja2)

프로젝트가 맨처음 시작할 때에는 큰 구조로 기획되었고, 그에 따라 많은 html이 필요해서

공통적으로 필요한 요소를 base.html/css/js로 놓고,
Flask의 템플릿 엔진인 Jinja2를 사용해서 extend하는 방식으로 구조를 짜려고 했다.

그러나 비즈니스 방향이 급선회하며

SPA 기본 템플릿을 만든 뒤에 데이터를 꽂아서 생산하는 식의 전개가 되었다. (거의 들어 엎었다.)

그렇다고 해도 html을 Python으로 읽도록 서포트해주는
Jinja2는 기상천외한 부분에서 제 역할을 해줬다.
flask에서 선처리한 데이터를 변수로 넘겨 render할 뿐만 아니라,

html 내부에서 조건문과 제어문을 사용하여 Element와 Node의 생성, 제거, 데이터 변경 처리,
심지어는 flask에서 정의한 함수도 객체로 토스하면 html 렌더링 단계에서 실행해버리는 기염을 토했다.

여러모로 DB에서 뽑아오는 정적인 value들을 처리하는 데에 효자 노릇을 톡톡히 한 듯.

1-2. js (summernote, ajax)

Ralphrio님이 js에 힘을 쏟을 수 있는 상황이 아니었다.
외관이 중요한 서비스라 더 앞쪽에 힘을 쏟을 수 밖에 없는 상황이었다.
summernote를 통해 간접적으로 ajax를 다뤘다. (현재 서비스에서는 모듈만 준비해두고 적용은 되지 않은 상태이다.)
ajax를 시도할 수 밖에 없었던 이유는 WYSIWYG에디터인 summernote가 이미지를 불러올 때

base64로 인코딩하는 점 때문이었다.

당연히 에디터 입장에서는 거기까지 하는 게 맞지만, base64로 인코딩된 텍스트를
DB에 저장하고 꺼내오는 것은 너무 비효율적이었다.
그래서 summernote에서 발생하는 imageupload를 처리할 ajax를 도입하고, 콜백을 post로 보낸 후
flask 엔드포인트에 post method로 받아 boto3로 연결해 s3로 보내는 루트를 짰다.
그리고 리턴을 s3 객체 url로 주어서 summernote에서 img 태그로 입력되도록 했다.

그 이후로는 이미지를 업로드할 때 s3로 업로드 되고 img로 형성되었다.
그러나 쓰이지 않는 이미지를 어떻게 뽑아내서 주기적으로 분리수거해 줄지는 아직 고민이 더 필요하다.


2. Flask

Flask는 자체가 마이크로 웹 프레임워크라
가볍고 빠르게 만들 수는 있었지만 추가 기능을 만드는 게 어려웠다.
그래서 Flask에 연계되어 있는 파생 라이브러리를 많이 썼다.

Flask-Mail
Flask-Migrate
Flask-SQLAlchemy
Flask-WTF

+ 식구로 딸려온 부모/자식 라이브러리들

2-1. Flask-Mail

smtp 쪽을 열어서 메세지를 보낼 수 있게 만드는 라이브러리,
flask가 가지고 있는 render_template 메소드를 이용해서 단순 텍스트가 아니라 html로 송신할 수 있다.

이메일 인증 방식에서 위 부분이 많이 도움이 되었다.
token generate, confirm 과정에서 잘 작동해 주었음.

2-2. Flask-Migrate/SQLAlchemy

python-mysql-connector, Flask-Sqlalchemy 등과 같이 쓰였다. DB와 Flask의 연결을 관여하는 부분이므로 DB 부분에 후술!

2-3. Flask-WTF

객체로 form 요소를 올린다음 Jinja2로 렌더링해서 form control에 기여하도록 도입했으나, 후반부에는 Ralphrio님이 JS로 input을 많이 컨트롤 해 주셔서 csrf 용도로 많이 썼다.
(물론 csrf도 WTF에서 많이 벗어났다. 후에 코드 일관성을 위해 보수해야 할 듯)


3. MySQL(AWS RDS, HeidiSQL)

가장 대중적인 MySQL(책에서 그랬다.)을 사용했다.
AWS RDS 위에서 돌린다.
데이터베이스 규모가 커지거나 용도에 따라서
다른 SQL류로 넘어가거나 NoSQL을 덧대야 할 필요성을 느낀다.

하지만 지금은 MySQL이 서비스에 맞는 기능을
충실히 잘 할 수 있다고 생각한다.

여기에 SQLAlchemy를 더해서 Flask에서 데이터를 다룰 수 있도록 처리했는데, 거기서 ORM을 채택했다.

ORM??

변명이지만, SQL을 학습해서 자유자재로 다룰 수 있게 만들기에는 회사에서 원하는 결과에 도달하기에 턱없이 시간이 모자랐다.

쿼리를 문장으로 제대로 던질 줄 아는 게 근본이지만,
당장 친숙한 것이 그나마 Python 문법이었기 때문에 선택했다. ORM으로 데이터를 콜해오는 것과 Query로 콜해오는 데에는
규모가 커질 수록 속도 차이가 있을 것이라 예상하고 있다.

HeidiSQL??

비주류 DBMS라는 것은 알고 있다(...) 그러나 물개와 돌고래가 꽤 밀어주는 것 같고, 패키지에도 포함되어 있어서 사용하게 되었다. 간단한 인터페이스와 빠른 접근성 때문에 선택했다.


4. AWS

Elastic Beanstalk
CodePipeline
S3
RDS

Elastic Beanstalk

물론 EC2를 차근차근 학습하면서 AWS 생태를 정확히 이해하는 게 중요하다는 것은 알고 있었지만, vpc, subnet, load balancer, ec2를 하나의 몸통으로 자동 처리해주는 EB를 채택했다.

앞서도 이야기한 것처럼, 빠르고 정확하게 결과에 도달하는 것이 최우선 기준이었기 때문에 선택한 것들이 많다. EB도 그 중 하나이다.

NginX를 통해 프로젝트가 배포되는데, 구동하는 중에 ebextension이나 conf로 설정을 덮어 씌워줘야 하는 부분이 있었다. (https)

EB의 프리셋을 덮어씌워 수정하는 것보다
내가 잘 아는 서비스들을 준비하고 연계하고
인프라에 직접 접근해서 수정하는 것이 더 근본이지만,
역시나 빠르고 정확한 것이 최우선 기준이었다.

CodePipeline

개발자가 많지 않은 환경에서 source - confirm - deploy를 처리하고 rollback하는 데에 제격이었다. Github자체에 경로를 꽂아두고 빠르게 배포하여 instance에 적용하였다.

S3

static한 요소들을 저장해 두기 위해 bucket을 두고 쓴다. 지금은 이미지들을 저장하고 있지만, 여기저기서 template에 연관된 (html, css, js) 파일들도 버킷에 업로드하고 쓴다는 이야기를 들어서
고민 중이다. 지금은 프로젝트 패키지가 뚠뚠이다.

데이터 교류는 파이썬 단계에서 boto3 (필요시 pillow)를 이용하여 토스한다. 불러올 땐 url로.

RDS

MySQL 엔진으로 돌아가고 있으며 EB에 인바운드를 걸어서 데이터를 송수신한다. 작업할 때는 원격 제어를 할 수 있도록 ip를 그 때 그 때 허용하는 식으로 다루는 중이다.


이상 heradee 프로토타입에 대한 정리 끝!
중요한 변화가 있으면 아마 시리즈에 글들이 추가될 것이다.

profile
devrmsrms

0개의 댓글