-
RESUT API를 제공하는 웹서비스를 Resutful API라고 함.
- Rest :: Network상에서 Client와 Server 사이의 통신 방식 중 하나
- URI는 자원을 표현하는 데에 집중하고 행위에 대한 정의는 HTTP Method를 통해 하는 것이 REST한(CRUD) API를 설계하는 중심 규칙을 가지고 있음
- CRUD Operation
1. Create
2. Read
3. Update
4. Delete
5. HEAD: Header 정보 조회
왜 REST가 필요한가?
1. 다양한 클라이언트
2. 애플리케이션 분리 및 통합
3. 멀티 플랫폼 지원
REST 구성 요소
1. 자원: Url, 클라이언트는 Url을 통해 자원을 지정하고 조작을 서버에 요청
2. 행위: HTTP Method
3. 표현: XML, JSON, TEXT 등 (json, xml이 일반적)
그냥 하나 만들어보자
플라스크를 이용했다.
유투브 url을 넣어서 서버에 저장하는 코드를 작성했다.
특정 카테고리를 입력하면 해당 url 중 랜덤으로 하날 추천했다.
이름하야... 유사 유투바 알고리즘..
from flask import Flaskfrom flask_restx import reqparse, abort, Api, Resourcefrom collections import defaultdictfrom pytube import YouTubeimport randomimport sslssl._create_default_https_context = ssl._create_unverified_contextapp = Flask(__name__)api = Api(app,version='0.1',title="유사 유투바 알고리즘",description="유투바의 알고리즘을 따라잡자!",terms_url="/youtube")url_dic = defaultdict(dict)parser = reqparse.RequestParser()parser.add_argument('url')parser.add_argument('category')just_category_parser = reqparse.RequestParser()just_category_parser.add_argument('category')def abort_category(category):if category not in url_dic:abort(404, message="Category {} doesnt' exist".format(category))def abort_url(category, url):if url not in url_dic[category]:abort(404, message="url {} doesnt' exist in Category {}".format(url, category))@api.route('/youtube')class Url(Resource):@api.expect(just_category_parser)def get(self):""" 지정된 카테고리의 url을 무작위로 추출합니다. """global url_dicargs = just_category_parser.parse_args()category = args['category']abort_category(category=category)return random.choice(list(url_dic[category].values()))@api.expect(parser)def delete(self):""" 유투브 url을 삭제합니다. """global url_dicargs = parser.parse_args()category = args['category']url = args['url']abort_url(category=category, url=url)del url_dic[category][url]return '', 204@api.expect(parser)def put(self):""" 유투브 url을 삽입합니다. """args = parser.parse_args()global url_diccategory = args['category']url = args['url']yt_name = str(YouTube(url).title)if url in url_dic[category]:return '이미 추가하신 곡입니다', 202else:url_dic[args['category']][url] = yt_namereturn_value = url_dic[category][url]return return_value, 201@api.route('/youtube/<string:category>')class Url_list(Resource):def get(self, category):""" 특정 카테고리의 url을 모두 보여줍니다."""global url_dicreturn url_dic@api.route('/yotube/all')class Url_list_all(Resource):def get(self):""" 전체 url 목록을 보여줍니다. """global url_dicreturn url_dicapi.add_resource(Url, '/youtube')api.add_resource(Url_list, '/youtube/<string:category>')api.add_resource(Url_list, '/youtube/all')if __name__ == '__main__':app.run(debug=True, host='0.0.0.0', port=4444)하지만 서버가 reset 될때마다 내 소중한 노동요 리스트들이 사라졌다..
db를 연결해주자.
database.py
from sqlalchemy.ext.declarative import declarative_basefrom sqlalchemy import Column, StringBase = declarative_base()class url_list(Base):__tablename__ = 'url_list'url = Column(String(1000), primary_key=True)category = Column(String(100))url_name = Column(String(100))def __init__(self, url, category, url_name):self.url = urlself.category = categoryself.url_name = url_namedef insert_url(session, url, url_name, category):try:new_info = url_list(url=url, category=category ,url_name=url_name)session.add(new_info)session.commit()except Exception as e:print("\nUnique value insert exception\n")session.rollback()def delete_url(session, url):deleted_objects = url_list.__table__.delete().where(url_list.url.is_(url))session.execute(deleted_objects)session.commit()def select_url(session, category=None):if category is not None: #전체 다 보여urls = session.query(url_list.url_name, url_list.url)\.filter(url_list.category == category).all()else:urls = session.query(url_list.category, url_list.url_name, url_list.url).all()return urlsapp.py
import sqlalchemyfrom flask import Flaskfrom flask_restx import reqparse, abort, Api, Resourcefrom collections import defaultdictfrom pytube import YouTubefrom sqlalchemy.orm import sessionmakerimport database as dbimport randomimport sslssl._create_default_https_context = ssl._create_unverified_contextapp = Flask(__name__)api = Api(app,version='0.1',title="유사 유투바 알고리즘",description="유투바의 알고리즘을 따라잡자!",terms_url="/youtube")url_dic = defaultdict(dict)parser = reqparse.RequestParser()parser.add_argument('url')parser.add_argument('category')just_category_parser = reqparse.RequestParser()just_category_parser.add_argument('category')just_url_parser = reqparse.RequestParser()just_url_parser.add_argument('url')@api.route('/youtube')class Url(Resource):@api.expect(just_category_parser)def get(self):""" 지정된 카테고리의 url을 무작위로 추출합니다. """global url_dicargs = just_category_parser.parse_args()category = args['category']category_url_list = db.select_url(session=dbconnect(), category=category)if category_url_list:return random.choice(list(category_url_list)),201else:return "해당 카테고리에 url이 존재하지 않습니다!"@api.expect(just_url_parser)def delete(self):""" 유투브 url을 삭제합니다. """global url_dicargs = just_url_parser.parse_args()url = args['url']db.delete_url(session=dbconnect(),url=url)return f'{url} 삭제 완료!', 201@api.expect(parser)def put(self):""" 유투브 url을 삽입합니다. """args = parser.parse_args()global url_diccategory = args['category']url = args['url']yt_name = str(YouTube(url).title)if url in url_dic[category]:return '이미 추가하신 곡입니다'else:db.insert_url(session=dbconnect(), url=url, category=category, url_name=yt_name)return_value = "{}:{}".format(yt_name, url)return return_value, 201@api.route('/youtube/<string:category>')class Url_list(Resource):def get(self, category):""" 특정 카테고리의 url을 모두 보여줍니다."""return db.select_url(session=dbconnect(), category=category), 201@api.route('/youtube/all')class Url_list_all(Resource):def get(self):""" 전체 url 목록을 보여줍니다. """return db.select_url(session=dbconnect()), 201api.add_resource(Url, '/youtube')api.add_resource(Url_list, '/youtube/<string:category>')api.add_resource(Url_list_all, '/youtube/all')def dbconnect():engine = sqlalchemy.create_engine('sqlite:///youtube.db')Session = sessionmaker(bind=engine)return Session()if __name__ == '__main__':engine = sqlalchemy.create_engine('sqlite:///youtube.db')db.Base.metadata.create_all(engine)app.run(debug=True, host='0.0.0.0', port=1919)완성본은 아래와 같음.
내가 디비에 put한 데이터들 중에서
랜덤으로 음악 url을 추천해주도록 설계되어있음.
아래처럼 간단하게 웹 붙여서 요즘 필요할 떄 듣는다.. ㅎㅎ
Reference
gmlwjd9405.github.io/2018/09/21/rest-and-restful.html
위지원데이터 엔지니어로 근무 중에 있으며 데이터와 관련된 일을 모두 좋아합니다!. 특히 ETL 부분에 관심이 가장 크며 데이터를 빛이나게 가공하는 일을 좋아한답니다 ✨
'2021년 > 개발공부' 카테고리의 다른 글
맥에서 Go 설치하기 (0) 2021.03.18 파이썬 유닛테스트 (0) 2021.03.18 스프링 시작하기 #2 (0) 2021.03.09 Intellij+git (0) 2021.03.08 스프링 시작하기 #1 (0) 2021.03.08