문제상황
해결방법
코드단에서 스웨거 패키지를 이용하여 코드 작성과 동시에 api문서를 정리 할 수 있어 시간적으로 단축
서버가동과 동시에 요청을 보낼 수 있는 문서도 같이 만들어 지기 때문에 url하나만 주면 프론트엔드가 쉽게 요청을 테스트 가능
swagger
개발자가 REST API 서비스를 설계, 빌드, 문서화할 수 있도록 하는 프로젝트 이다.
적용방법
from flask_restx import Api,Resource
class Services:
pass
def create_app(test_config=None):
app=Flask(__name__)
CORS(app)
api=Api(app,title='cloudy back-server api docs',doc='/api-docs')
if test_config is None:
app.config.from_pyfile("config.py")
else:
app.config.update(test_config)
database=create_engine(app.config['DB_URL'],encoding='utf-8',pool_recycle=app.config['POOL_RECYCLE'],pool_size=app.config['POOL_SIZE'],max_overflow=app.config['MAX_OVERFLOW'])
print("mysql 데이터베이스 연결 성공")
es=Elasticsearch(hosts=app.config['ELASTIC_URL'])
print("elastic 데이터베이스 연결 성공")
@app.before_request
def block_method():
if 'x-real-ip' in request.headers:
ip=request.headers['x-real-ip']
else:
ip=request.environ.get('REMOTE_ADDR')
print("Current IP Address:",ip,flush=True)
print("Current Process:",os.getpid(),flush=True)
splited_ip=ip.split('.')
ip_range=splited_ip[0]+'.'+splited_ip[1]
if ip not in app.config['GOOD_IP_LIST'] and ip_range not in app.config['GOOD_IP_RANGE']:
abort(403)
@api.route("/search")
class search_user(Resource):
def get(self):
headers = {'Content-Type': 'text/html'}
return make_response(render_template('index.html'),200,
headers)
@api.route("/ping")
class ping(Resource):
def get(self):
'''back 작동 테스트를 위한 api입니다.'''
return make_response("pong",200)
user_dao=UserDao(database)
image_dao=ImageDao(database)
room_dao=RoomDao(database)
services=Services
services.user_service=UserService(user_dao,app.config)
services.image_service=ImageService(image_dao,app.config)
services.room_service=RoomService(room_dao,app.config)
oauth_router(api,services,app.config)
user_router(api,services,app.config,es)
room_router(api,services)
image_router(api,services)
return app
app=create_app()
1.flask_restx 패키지 설치
pip install flask_restx
2.flask의 app클래스를 포함하는 새로운 flask_restx의 app 생성
api=Api(app,title='cloudy back-server api docs',doc='/api-docs')
*마지막 인자인 doc은 스웨거의 문서가 정리되는 url이다
3.api에 라우터를 적용하기 위해 api생성시 인자에 스웨거의 app클래스 전달
user_router(api,services,app.config,es)
4.router 파일에서 전달받은 스웨거의 app클래스에 Namespace클래스와 add_namespace메서드를 이용하여 라우터를 추가
from flask_restx import Resource,Namespace
image_namespace=Namespace('image',description='이미지의 정보를 생성,호출,수정,삭제 합니다.')
def image_router(api,services):
image_service=services.image_service
room_service=services.room_service
api.add_namespace(image_namespace,'')
...
*Namespace의 첫번째 인자는 라우터를 나눌 기준인 url keyword를 명시한다.
5.추가한 namespace의 메서드를 이용하여 스웨거 문서에서 받을 인자와 response값들을 미리 명시해 준다.
@image_namespace.route("")
class image(Resource):
@image_namespace.expect(post_image_parser,validate=False)
@image_namespace.response(200,'저장된 이미지의 정보를 반환합니다.',post_image_response_model)
def post(self):
*class의 이름은 중복이 되면 안된다.
*expect 메서드는 querystrging과 헤더를 명시하는 parser,json을 명시하는 model을 설정
*response 메서드는 response시에 전달 받을 json model과 상태코드와 설명을 명시
6.스웨거의 app 생성시 명시한 url을 접속하여 테스트
결과
front에서는 요청을 보내는 프로그램이 필요 없이 스웨거의 url에 접속하여 이미 설정해둔 인자값들만 기입하여 요청을 보내기에 편리
back에서는 코드를 생성함과 동시에 문서정리가 되기 때문에 효율적 문서정리 가능