API서버 - 클라이언트로부터 특정 정보의 값 출력하기 (GET)

이번 포스팅은 DB와 연결하여 클라이언트가 특정 값을 출력(목록)하는 방법을 설명합니다.

DB 연동 과정은 이전 포스팅을 참고해주세요.

https://luvris2.tistory.com/182

 

API서버 - DB 연동하기

API서버 DB연동하기 DB : MySQL Programming language : Python IDE : Visual Studio Code MySQL DB 생성 (recipe) Table 생성 (recipe, user) DB를 관리 할 수 있는 권한 설정하기 (MySQL) SQL 쿼리 use mysql;..

luvris2.tistory.com


Visual Studio Code

API 서버 구축하기

  • 메인 파일 이름 : app.py
  • 서버 URL : 로컬호스트/recipes/숫자
    • 입력 받은 숫자의 해당하는 DB의 값을 호출
# app.py
from flask import Flask
from flask_restful import Api
from resources.recipe import RecipeListResource # 원하는 갯수만큼 출력
from resources.recipe_info import RecipeResource # 특정 정보만 출력

# API 서버를 구축하기 위한 기본 구조
app = Flask(__name__)

# restfulAPI 생성
api = Api(app)

# 경로와 리소스(api코드) 연결
api.add_resource(RecipeListResource, '/recipes') # /recipes? 쿼리스트링 이용
api.add_resource(RecipeResource, '/recipes/<int:recipe_id>') # /recipes/숫자

if __name__ == '__main__' :
    app.run()

 

기능 설계 - 쿼리 스트링을 이용하여 데이터 갯수만큼 출력하기

  • 추가 리소스 파일 : recipe.py
  • 기능 : 목록 보여주기 (Class=RecipeListResource)
  • 쿼리 스트링으로 오는 데이터는 request.args.get('문자열')로 처리하여 변수에 저장 
    • Query String(쿼리 스트링) : URL에서 물음표(?) 뒤에 위치, 사용자의 입력을 전달하는 역할
      • 예시) 'limit=3' , a=request.args.get('limit')
        a >>> 'limit=3'
  • 쿼리 스트링으로 전달 받은 값으로 DB의 데이터 입력 받은 값만큼 목록 출력
  • fetchall : select 문의 결과값을 배열로 저장
  • json은 문자형으로 데이터 교환이 이루어지기 때문에 시계열타입을 문자열로 변경
  • 코드 수행 성공 문구, 호출한 데이터의 갯수, 데이터의 값 반환
from flask import request
from flask_restful import Resource
import mysql.connector
from mysql_connection import get_connection # DB 연동 사용자 파일

class RecipeListResource(Resource) :
	def get(self):
        # 쿼리 스트링으로 오는 데이터는 아래처럼 처리해준다.
        offset = request.args.get('offset')
        limit = request.args.get('limit')

        # DB로부터 데이터를 받아서 클라이언트에 보내준다
        try :
            connection = get_connection()

            query = '''
                        select *
                        from recipe
                        limit
                    ''' + offset + ''',''' + limit + ''';'''

            # 딕셔너리 = 키 : 밸류 형태
            # 셀렉트문은 딕셔너리의 형태로 값을 호출한다.
            cursor = connection.cursor(dictionary=True)
            cursor.execute(query)

            # fetchall : 데이터를 배열 형태로 값을 가져온다.
            result_list = cursor.fetchall()
            
	    # DB의 TimeStamp 타입은 파이썬의 datetime으로 호출된다.
            # json은 문자열 구조로 데이터를 교환하기 때문에 문자열로 데이터타입을 변경한다.
            i = 0
            for record in result_list :
                result_list[i]['created_at'] = record['created_at'].isoformat()
                result_list[i]['updated_at'] = record['updated_at'].isoformat()
                i += 1

            cursor.close()
            connection.close()

        except mysql.connector.Error as e :
            print(e)
            cursor.close()
            connection.close()
            return {"error" : str(e)}, 503 #HTTPStatus.SERVICE_UNAVAILABLE

        # 정상적으로 됐을 때 200, 기본 값이므로 생략 가능
        return{
            "result" : "success",
            "count" : len(result_list),
            "result_list" : result_list
        }, 200

POSTMAN

API 기능 테스트

  • GET - 로컬호스트/recipes?
    • Params의 값을 입력해주면 쿼리 스트링 부분이 채워짐
  • Params - KEY/VALUE 값 입력 - Send
  • litmit=3 offset=0 : 인덱스 0에서 3개의 데이터 출력


Visual Studio Code

기능 설계 : 클라이언트로부터 특정 정보의 값 출력하기

  • 추가 리소스 파일 : recipe_info.py
  • 기능 : 특정 정보 보여주기 (Class=RecipeResource)
  • 숫자를 입력 받아(recipe_id) 해당 하는 정보 출력
  • 성공 문구, 호출한 데이터 갯수, 데이터의 값을 반환
import mysql.connector
from mysql_connection import get_connection
from flask_restful import Resource

class RecipeResource(Resource) :
    # 클라이언트로부터 /recipes/3 이런식으로 경로를 처리하므로 숫자를 변수로 처리해준다.
    def get(self, recipe_id) :
        # DB에서 recipe_id에 들어있는 값에 해당되는 데이터를 셀렉트 해온다.
        # DB로부터 데이터를 받아서 클라이언트에 보내준다.
        try :
            connection = get_connection()

            query = '''
                        select *
                        from recipe
                        where id = %s;
                    '''
            record = (recipe_id, ) # tuple
            cursor = connection.cursor(dictionary=True)
            cursor.execute(query, record)
            result_list = cursor.fetchall()
            i = 0
            for record in result_list :
                result_list[i]['created_at'] = record['created_at'].isoformat()
                result_list[i]['updated_at'] = record['updated_at'].isoformat()
                i += 1

            cursor.close()
            connection.close()

        except mysql.connector.Error as e :
            print(e)
            cursor.close()
            connection.close()
            return {"error" : str(e)}, 503 #HTTPStatus.SERVICE_UNAVAILABLE

        return{
            "result" : "success",
            "count" : len(result_list),
            "result_list" : result_list
        }, 200

POSTMAN

API 기능 테스트

  • GET - 로컬호스트/recipes/인덱스번호 입력
  • Send