본문 바로가기
IT 프로그래밍 관련/API server ( Flask )

API 서버 실제 구성 ( 데이터베이스 연결, API개발, 경로의 변수처리)

by 지나는행인 2021. 4. 8.
728x90

flask 기본적인 문법사항이나, 기본 사용법을 마치고,

 

실제로 API 서버 구성을 해보겠다.

위를 토대로 API 개발을 해본다.

 

일단 내가 하고 있지만 , 숙련되지 않고는 복잡하다.

 

먼저 데이터 베이스에서 테이블을 새롭게 만들었다. (recipe)

* recipe 테이블의 정보

현재 작성하고 있는 visual studio code에는 폴더를 여러개로 구성하여 , db, config 등 상황별에 맞춰 파일이 저장되어 있음을 참고한다.

 

먼저 이 데이터 베이스의 모든 정보를 가져오는(GET) API 를 만들어본다.

 

이 실제 API는 기문 문법에서 이용한 문법과는 다르게 , 클래스와 함수로 처리하는 부분이 많다.

 

먼저 데이터 베이스와 연결을 해주는 커넥터를 연결하기 위한 함수를 db 폴더의 db.py 파일에 작성하였다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import mysql.connector            #mysql과 연결하기 위한 커넥터
from mysql.connector import Error    # 연결 에러시 처리하기 위한 라이브러리
from config.config import db_config  # 아래의 커넥터의 변수처리
 
def get_mysql_connection():
    
try :
 
        connection = mysql.connector.connect( **db_config )
 
        if connection.is_connected() :
            print('connection ok!')
            return connection
 
    except Error as e:
        print('Error while connecting to MySQL', e)
        return None        
cs

 

위는 커넥터를 연결까지만 하는 함수이다. 이후에 이 함수를 이용하여 ,  연결 후 작업을 처리한다.

 

** db_config 의 부분에는 원래

 

host = '데이터베이스 호스트',

database = '데이터베이스이름',

user = '사용자',

password = '비밀번호'    이렇게 들어가는데, 이것은 중요한 정보임으로, 밖으로 들어나지 않도록 하기 위하여,

 

config폴더의 config파일의 db_config 변수로 저장하여 사용하였다.

 

커넥터의 문법상 **db_config으로 받는다.

1
2
3
4
5
6
7
8
 
## mysql 접속 정보를, 딕셔너리 형태로 저장한다.
 
 
db_config = { 'host' :'데이터베이스호스트',
        'database' : '데이터베이스이름',
        'user' : '유저이름',
        'password' : '비밀번호'   }

class Config : 
DEBUG = True

cs

( config폴더의 config파일)

키의 값은 수정한 값으로 , 사용한 호스트 및 데이터베이스 이름등으로 들어가야한다.

 

 

 

이제 API 서버를 실행하는 py파일을 만든다. ( app.py )

기본적인 import를 해주고 코드를 써보겠다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
from flask import Flask
from flask_restful import Api   # API 설정위한 .
from db.db import get_mysql_connection # 작성한 커넥션 함수
from config.config import Config #config파일의 Config클래스
from resources.recipe import RecipeListResource
 
 
app = Flask(__name__)
 
# 1. 환경변수 설정
app.config.from_object(Config)   # 환경변수를 설정한다. 현재는 Config클래스 내용으로
                                 # DEBUG 뿐이 없지만, 앞으로 더 많은 내용이 들어갈 예정
 
 
# 2. api설정
api = Api(app)   #API설정을 한다. 괄호안에는 위에서 받은 플라스크변수
 
# 3. 경로(Path)와 리소스(Resource)를 연결한다. 
# /recipes 
 
api.add_resource(RecipeListResource, '/recipes'#API서버는 리소스라는 것을 추가해야한다.
                                          #괄호안에는 임의로 만든 클래스명, 임의로만든 경로이다.
                                        #클래스에는 recipe테이블의 모든 데이터를 가져오려고 하니.
                                          #GET메소드가 함수로 들어간다. 경로는 
                                       #앞서 나의 경로였던, localhost:5000/뒤에 recipes를 붙인다는
                                          #뜻이다. 
 
#RecipeListResource클래스는 별로로 다른 폴더에 만들어 두었으니, 위에 import를 한다.
 
 
if __name__ == '__main__':
    app.run()
cs

위에 화면에서 이야기했듯이 리소스 추가를 위해서는 클래스를 생성하여 그 클래스에 우리가 행할 코드를 생성해야한다.

** 주의 : 이 글의 젤 위의 API설계 화면에 보면, URL이 같으면 resource의 클래스명이 같다.

            같은 URL일때는 같은 클래스명 아래서 , 서로다른 함수를 만들어가면서 추가한다.(GET,POST등)

            (api.add_resource api설계 추가시 계속 추가됨. 

 

 

resources폴더의 recipe.py파일의 RecipeListResource 클래스 만든것을 보면

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
from flask import request
from flask_restful import Resource   # 리소스 위한 .
from http import HTTPStatus  # HTTP 상태코드 전송위한.
from db.db import get_mysql_connection
 
 
# 이 파일에서 작성하는 클래스는, 플라스크 프레임워크에서, 
# 경로랑 연결시킬 크래스다. 따라서 클래스명 뒤에 상속한다는 
# Resource 클래스를 상속받아야한다.
# 플라스크 프레임워크의 레퍼런스에 나옴.
class RecipeListResource(Resource) :         # 괄호안에는 꼭 Resource로 상속받아야한다. 문법상!
    
    # get 메소드로 연결시킬 함수 작성
    def get(self) :          
        # recipe테이블에 저장되어 있는 모든 레시피 정보를 가져오는 함수
 
        # 1. DB 커넥션을 가져온다
        connection = get_mysql_connection()  # 작성한 함수 사용
 
        # 2. 커넥션에서 커서를 가져온다.
        cursor = connection.cursor(dictionary=True)
 
        # 3. 쿼리문을 가져온다.
 
        query = """select * from recipe;"""    # recipe테이블에서 모든 정보 가져옴.
 
        # 4. sql 실행
        cursor.execute(query)
 
        # 5. 데이터를 페치
        records = cursor.fetchall()
        print(records)
 
        ret = []
        for row in records :
            row['created_at'= row['created_at'].isoformat()   # 문자열로 바꾸기 iso포맷으로
            row['updated_at'= row['updated_at'].isoformat()   # date.date로 들어와서 
            ret.append(row)
 
        # 6. 커서와 커넥션을 닫아준다.    
        cursor.close()
        connection.close()
 
        # 7. 클라이언트에 리스펀스 한다.
        return {'count' : len(ret), 'ret' : ret}, HTTPStatus.OK
cs

이러한 코드 진행이 된다. 위의 클래스 코드 진행은 플라스크 문법상의 진행이다.

 

Resource로 상속 받는것은 무조건해야한다.

 

완성된 코드를 포스트맨으로 테스트해보면.

 

HTTP상태코드 포함하여 잘 출력된것을 알 수 있다.

댓글