-
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 Flask from flask_restx import reqparse, abort, Api, Resource from collections import defaultdict from pytube import YouTube import random import ssl ssl._create_default_https_context = ssl._create_unverified_context app = 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_dic args = 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_dic args = 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_dic category = args['category'] url = args['url'] yt_name = str(YouTube(url).title) if url in url_dic[category]: return '이미 추가하신 곡입니다', 202 else: url_dic[args['category']][url] = yt_name return_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_dic return url_dic @api.route('/yotube/all') class Url_list_all(Resource): def get(self): """ 전체 url 목록을 보여줍니다. """ global url_dic return url_dic api.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_base from sqlalchemy import Column, String Base = 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 = url self.category = category self.url_name = url_name def 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 urls
app.py
import sqlalchemy from flask import Flask from flask_restx import reqparse, abort, Api, Resource from collections import defaultdict from pytube import YouTube from sqlalchemy.orm import sessionmaker import database as db import random import ssl ssl._create_default_https_context = ssl._create_unverified_context app = 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_dic args = 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)),201 else: return "해당 카테고리에 url이 존재하지 않습니다!" @api.expect(just_url_parser) def delete(self): """ 유투브 url을 삭제합니다. """ global url_dic args = 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_dic category = 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()), 201 api.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
'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