Flask RESTful API - GET /stores/search (매장검색)

2019. 7. 3. 14:56Python/Flask

반응형

GET /stores/search

매장 정보 검색은 현재 위치에서 원하는 반경 내 검색을 하며 현재 위치에서 가장 가까운 거리 순으로 조회 결과를 반환한다.

Resource URL

http://localhost:5000/stores/search

Request 

http://localhost:5000/stores/search?y=126.7198326&x=37.6023079&radius=3000

Response

[

    {

        "abbr_address": "경기 김포시 풍무동 620-1",

        "distance": 264.31108875,

        "grade": null,

        "lat": 126.720585355265,

        "lon": 37.6000069299231,

        "phone": "031-998-6728",

        "road_address": "경기 김포시 풍무로 45-1",

        "store_id": 50,

        "store_name": "스타벅스 김포풍무DT점",

        "store_url": "http://place.map.kakao.com/23619799"

    },

    {

        "abbr_address": "경기 김포시 사우동 246-6",

        "distance": 1809.46873925,

        "grade": null,

        "lat": 126.717924540437,

        "lon": 37.6185104692286,

        "phone": "031-985-6745",

        "road_address": "경기 김포시 사우중로 35",

        "store_id": 51,

        "store_name": "스타벅스 김포시청점",

        "store_url": "http://place.map.kakao.com/24165747"

    }

]


소스코드 작성

소스코드 작성은 다음과 같이 작성한다.
  • Model 파일에 매장검색 메소드 추가
  • Resource 파일에 매장검색 메소드 추가
  • app.py 매장검색 Resource 정보 등록


store.py - Model


현재위치정보, 반경값에 맞는 매장 목록 조회

@classmethod
def find_stores_within_radius(self, point, radius, y, x):
	"""
	반경내 모든 매장 정보를 검색하여서 반환한다.

	param x: 경도(longitude)
	param y: 위도(latitued)
	param radius: 반경

	:return: stores: 검색조건에 해당하는 매장 정보 목록
	"""
	q = "SELECT store_id, store_name, abbr_address, road_address                                " \
		"     , phone, store_url, grade, lat, lon                                               " \
		"     , st_distance_sphere(st_makepoint(lat, lon),st_makepoint({}, {})) as distance     " \
		"  FROM store                                                                           " \
		" WHERE ST_DWithin(geo, ST_Transform(ST_GeomFromText(\'POINT({} {})\', 4326), 2097), {})" \
		" ORDER BY                                                                              " \
		"       st_distance_sphere(st_makepoint(lat, lon),st_makepoint({}, {})) asc             ".format(y, x, y, x, radius, y, x)

	stores = db.session.execute(q).fetchall()

	return stores


store.py - Resource


"""
GET /stores - 매장 목록 조회
"""
stores_schema = StoresSchema(many=True)

class Stores(Resource):

    # 입력 파라미터 설정
    parser = reqparse.RequestParser()

    parser.add_argument('y',
        type=float,
        required=False
    )
    parser.add_argument('x',
        type=float,
        required=False
    )
    parser.add_argument('radius',
        type=int,
        required=False
    )

    def get(self):
        # Request Parameter를 dictionary 형태로 저장
        data = Stores.parser.parse_args()

        # 위도
        y = data['y']

        # 경도
        x = data['x']

        # 뱐경
        radius = data['radius']

        point = '\'POINT({} {})\''.format(y, x)

        stores = StoreModel.find_stores_within_radius(point, radius, y, x)

        return stores_schema.jsonify(stores)



app.py


import os
import psycopg2

from flask import Flask
from flask_restful import Api
from flask_sqlalchemy import SQLAlchemy

from config import app_config

from resources.store import StoreRegister,StoresRegister,Stores

# set_env.bat 에서 설정한 application 이름 설정
app = Flask(os.getenv('FLASK_APP'))

# set_env.bat 에서 설정한 FLASK_ENV는 development
env_name = os.getenv('FLASK_ENV')
"""
app_config 는 config.py 에서 정의 app_config 이면 위에서 development를 설정하였기
때문에 config.py 의 Development 클래스의 정보가 설정 되게 된다.
"""
app.config.from_object(app_config[env_name])

# 데이터 변경사항에 대해 커밋 전후로 알림 여부
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

# Query Debug 여부
app.config['SQLALCHEMY_ECHO'] = False


"""
API Resource 등록
---------------------------------------------------------
POST /stores/create - 매장 등록
PATCH /stores - 벌크 매장 등록
GET /stores - 매장목록 조회
GET /stores/search - 매장정보조회
PUT /stores/<int:store_id> -매장정보수정
DELETE /stores/<int:store_id> - 매장정보삭제
"""
api = Api(app)
api.add_resource(StoreRegister, '/stores/create')
api.add_resource(StoresRegister, '/stores')
api.add_resource(Stores, '/stores/search')

if __name__ == "__main__":
    from db_init import db
    db.init_app(app)
    app.run(debug=True,port=5000)


테스트


입력 파라미터 설정 및 테스트 결과


반응형