본 프로젝트는 Novice 구성원들이 BackEnd 분야를 쉽고 재밌게 체험할 수 있도록 구성한 BackEnd 트랙의 CodeLab 입니다.
본 문서를 단계별로 따라가는 것으로 간단하게 MVC패턴으로 이루어진 API 서버를 직접 구동해보고 사용해 볼 수 있을 것입니다.
프로젝트는 Python의 Flask를 이용하여 제작하였습니다.
Python은 초보자도 쉽게 배우고 간단히 이용할 수 있는 강력한 프로그래밍 언어입니다.
Flask는 Python을 이용하여 웹 서버를 쉽게 제작할 수 있게 해주는 도구입니다.
이 글을 읽는 많은 분들이 아직까진 C 계열 언어의 학습 및 기초적인 CSE 이론을 끝마치셨을 것이고, 갑자기 쏟아지는 새로운 용어들에 당황하셨을 것이라 생각합니다.
그래서 프로젝트를 살펴보기에 앞서 중요한 용어들에 대해 간략히 설명하도록 하겠습니다.
BackEnd
웹 사이트는 크게 FrontEnd와 BackEnd로 구분되는데, 이름에서 알 수 있듯 FrontEnd는 실제 사용자의 눈에 보이는 디자인이나 버튼 등을 담당하는 영역이며 BackEnd는 눈에 보이지 않는 뒤편의 데이터베이스, 서버 관리 등을 담당하는 영역입니다.
게시판 글을 작성하는 화면이나 회원 정보를 수정하는 화면은 FrontEnd에서 관리하고 게시판 글의 내용이나 회원 정보는 BackEnd에서
관리한다고 생각하시면 됩니다.
API
그렇다면 누군가가 게시판에 글을 적었을 때, 그 내용을 서버로 전송하는 작업도 필요할 것입니다. API는 서버에서 제공하는 일종의 도구로써, 호출을 통해 특정 목적을 달성할 수 있게 도와줍니다.
지금 같은 경우는 게시판에 작성한 글의 내용을 서버의 특정 API를 요청하여 데이터베이스에 등록해주고 이로써 게시판을 이용하는 다른 사람들도 그 글을 볼 수 있게 해주는 겁니다.
MVC 패턴
MVC(Model-View-Controller) 패턴은 위 예시로 든 작업을 수행하기 위한 구성 형태로, 사용자와의 상호작용(View), 데이터의 관리(Model), 이 둘 간의 연결(Controller)을 분리한 아래 그림과 같은 형태를 띕니다.
이제 완성된 프로젝트를 직접 다뤄보면서 단계별로
- 환경 구성
- 서버 구동
- API 이용
- 프로젝트 분석
- 프로젝트 수정 (선택)
을 수행해보겠습니다.
서버가 올바르게 동작하기 위해선 올바른 환경을 구성하는 것이 중요합니다.
본 프로젝트에선 python언어와 그 라이브러리 flask를 사용합니다.
IDE로는 pycharm을 사용했습니다. 데이터베이스로는 sqlalchemy를 사용합니다.
-
python 설치 : https://www.python.org/downloads/ (본 프로젝트는 3.7 버전을 사용했습니다)
-
flask 설치 : python의 설치를 올바르게 완료했다면 pip도 함께 설치가 완료됩니다.
커맨드창 혹은 python경로에서 pip를 실행하여pip install flask명령어로 flask를 설치해줍시다. -
flask_sqlalchemy 설치 : flask_sqlalchemy는 flask와 데이터베이스를 이용하기 위해 필요한 도구입니다. flask를 설치했을 때와 동일하게
pip install flask_sqlalchemy명령어로 설치해줍시다. 선행 라이브러리 등은 pip가 자동으로 관리해줍니다. -
pycharm 설치 : https://www.jetbrains.com/pycharm/
pycharm은 선택적으로 설치하셔도 됩니다. 다른 python IDE가 이미 설치되어 있으시다면 이용하셔도 좋습니다.
서버는 환경만 잘 갖추어져있다면 쉽게 구동시킬 수 있을 겁니다.
단순히 프로젝트 경로로 이동하여 app.py를 python으로 실행하시면 됩니다.
app.py가 존재하는 경로에서 python app.py 명령어로 프로젝트를 실행시키면 다음과 같은 결과가 출력될 것입니다.
In folder C:/.../BCSD-BackEnd-CodeLab
C:\...\python.exe -m flask run
* Serving Flask app "app.py"
* Environment: development
* Debug mode: off
...
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
마지막에 출력된 * Running on http://127.0.0.1:5000/ (...) 이 바로 현재 http://.../ url로 서버가 실행되고 있다는 뜻입니다.
브라우저를 열어 해당 url을 입력했을 때 문제없이 초기화면이 나온다면 서버가 잘 동작하고 있는 것입니다.
처음에 말씀드렸듯이 API는 서버에서 제공하는 일종의 도구라고 할 수 있습니다. 현재 url로 접속하여 보여지는 화면은 FrontEnd의 영역으로, 여기서 만약 글을 작성하여 게시판에 공개하고 싶다면 BackEnd의 API를 이용해서 작성글의 정보를 서버로 보내는 것이죠.
화면의 '글쓰기'를 눌러서 글 작성 화면으로 이동합시다.
작성자, 제목, 내용을 채우고 submit을 누르면 게시판에 글이 올라가게 됩니다.
"API 이용" 에서 수행한 일련의 동작이 이제 내부적으로는 어떻게 진행되는지 살펴보도록 하겠습니다.
url 형식으로 들어온 요청은 우선 Controller로 전송됩니다. 코드에는 [ CONTROLLER ]라는 주석으로 시작하는 부분입니다.
맨 처음엔 우선 http://url/ 위치로 이동하므로 '/'가 목적지(route)로 설정된 index() 함수가 호출됩니다.
index() 함수는 Model의 getArticleList() 함수를 호출하여 게시글의 리스트를 데이터베이스에서 가져오고 이를 화면에 그려줄 수 있게 해줍니다.
Model 도 Controller 처럼 코드에 [ MODEL ]라는 주석으로 시작하는 부분입니다.
초기화면에서 '글쓰기'를 클릭하면 링크된 url인 http://url/article로 이동하게됩니다.
index()의 경우와 동일하게 '/article'이 route로 설정된 Controller의 article() 함수가 호출됩니다.
여기서 request가 POST인지, GET인지로 나뉘게 되는데,
이는 url요청의 종류로, 이름에서 알 수 있듯 대게 GET은 정보를 가져오는 요청, POST는 정보를 전송하는 요청으로 사용됩니다.
현재는 게시글 작성 화면을 보기 위해 GET요청을 한 상태이므로 if문에 진입하지 않고 return render_template('post_article.html') 코드로 화면을 그려주게 됩니다.
게시글 작성 화면에서 내용을 적고 submit 버튼을 클릭하면 이번에도 http://url/article로 요청을 전송하게 됩니다. 하지만 이번에는 POST 방식으로 작성한 글의 정보와 함께 서버로 요청하게 됩니다.
이제 article() 함수의 if request.method == 'POST' 분기로 진입해 Model의 postArticle(...) 함수를 호출하여 실제 데이터베이스에 정보가 삽입되도록 하고 작업이 끝나면 redirect('index') 코드로 초기화면으로 이동합니다.
Model의 postArticle(...)에선 무슨 일이 일어나는지 살펴보도록 하겠습니다.
postArticle(data) 함수의 인자인 data에는 사용자가 입력한 데이터가 dictionary 형태로 전달됩니다.
dictionary는 'key':'value' 형식의 자료형입니다. 예를 들면 {'id':1, 'author':'이름', 'title':'제목'}이 dictionary 형태라 할 수 있습니다.
data는 데이터베이스에 정보를 입력하기 위한 클래스인 Article의 생성자에 인자로 입력됩니다. 단순히 생성된 객체를 db.session.add(...) 함수의 인자로 넘겨주고 db.session.commit() 으로 변경사항을 확정지음으로써 데이터베이스에 게시글 정보를 삽입하는 작업이 완료됩니다.
지금까지 서버를 구동해보고 직접 이용해보면서 MVC, API를 이해해보았습니다. 이제는 그러한 이해를 바탕으로 프로젝트에 약간의 수정을 가해보겠습니다.
지금의 프로젝트로 게시글을 다양하게 만들어보신 분들 중에는 작성자와 글 제목을 공백으로 둬도 작성이 되는 것을 확인한 분도 있을 겁니다. 이번 단계에선 postArticle(...) 함수에 수정을 가해서 그러한 동작을 막아 보겠습니다.
우린 이미 사용자가 보내온 데이터를 postArticle(...)의 인자인 data로 전달받았습니다. 작성자명과 제목에 공백입력을 막아주기 위해선
data['author']와 data['title']의 값이 공백인지 아닌지 판단하면 될 것입니다. 이를 위한 코드가 주석처리된 118, 119번째 줄의 코드입니다.
not data['author'].strip() 이란 코드는 문자열인 data['author']를 strip() 메소드로 앞,뒤의 공백을 제거한 후, not으로 그 결과가 '' 인지 판단하는 코드입니다.
만약 data['author']가 ' ' 라면 strip() 에 의해 ''로 변하고 python에서 ''은 false로 평가되기 때문에
not false 즉, true가 되어 데이터베이스에 삽입되지 않게 됩니다.
지금은 그저 데이터에 삽입되는 것을 막기만 하지만 데이터가 삽입되지 않을 때 이를 알려주는 결과를 FrontEnd로 전송하여 "게시글 작성에 실패했음"과 그 원인을 화면에 출력한다면 더 좋은 웹사이트가 될 것입니다.
지금까지 python flask를 이용하여 간단히 서버를 구동해보고 게시글 작성 api를 이해하고 수정하며 BackEnd 분야에 대해서도 간단히 체험해보았습니다. BackEnd는 이렇게 서버단에서의 api 코드 작성 등의 역할도 있지만, 데이터베이스 관리, 서버 구축 및 유지보수 등 넓고 다양한 분야를 담당합니다. 추가로, 프로젝트의 서버 부분은 상세히 주석이 달려있으니 원하신다면 개인적으로 더 살펴보면서 수정하셔도 좋습니다.
비록 어렵게 느껴지는 순간이 있더라도 그만큼 넘어섰을 때의 성취감과 경험은 확실히 보장되어있습니다. 많은 Novice분과 다시 만나뵐 것을 기대하며 끝마치도록 하겠습니다. 다들 수고하셨습니다. :D