📝 REST란 무엇인가 ?

REST : Representational State Transfer

= 자원을 이름(자원의 표현)으로 구분하여 해당 자원의 상태를 주고 받는 것을 의미한다.
= 즉, 자원(resourece) 의 표현(representation)에 의한 "상태 전달"

  • 자원의 표현
    • 자원 : 해당 소프트웨어가 관리하는 모든 것 ( ex. 그림, 문서, 데이터 등 )
    • 자원의 표현 : 그 자원을 표현하기 위한 이름
  • 상태(정보) 전달
    • 데이터가 요청되는 시점에서 자원의 상태(정보)를 전달한다.
    • JSON 혹은 XML을 통해 데이터를 주고 받는 것이 보통의 전달 방식이다.

WWW(World Wide Web) 와 같은 시스템을 위한 소프트웨어 개발 아키텍처의 한 형식이다.

REST는 기본적으로 웹의 기존 기술과 HTTP 프로토콜을 그대로 사용하기 때문에, 웹의 장점을 최대한 활용할 수 있는
아키텍처 스타일이다. REST는 네트워크 상에서 클라이언트와 서버 사이의 통신 방식 중 하나이다.

 

💡 REST의 구체적인 개념

HTTP URI(Uniform Resource Identifier)을 통해 자원을 명시하고, HTTP Method(POST, GET, PUT, DELETE)를 통해 해당 자원에 대한 CRUD Operation을 적용하는 것을 의미한다.

  • REST는 자원 기반의 구조(ROA) 설계의 중심에 자원이 있고, HTTP Method를 통해 자원을 처리하도록 설계된 아키텍쳐를 의미한다.

💡 CRUD

  • Create : 생성(POST)
  • Read : 조회(GET)
  • Update : 갱신(PUT)
  • Delete : 삭제(DELETE)
  • HEAD : header 정보 조회(HEAD)

💡 REST 장단점

장점

  • 서버와 클라이언트의 역할을 명확하게 분리한다.
  • 여러가지 서비스 디자인에서 생길 수 있는 문제를 최소화한다.
  • REST API 메시지가 의도하는 바를 명확하게 나타내므로, 의도하는 바를 쉽게 파악할 수 있다.
  • HTTP 표준 프로토콜에 따르는 모든 플랫폼에서 사용이 가능하다.
  • HTTP 표준 프로토콜의 표준을 최대한 활용하여 여러 추가적인 장점을 함께 가져갈 수 있게 해준다.

단점

  • 사용할 수 있는 메소드가 4가지 밖에 없다. (POST,GET,PUT,DELETE)
  • 표준이 존재하지 않는다.

💡 그럼에도, REST가 왜 필요한가 ?

  • 다향한 클라이언트의 등장
  • 애플리케이션 분리 및 통합

최근 서버 프로그램은 다양한 브라우저(chrome, Explorer, safari 등)와 안드로이드폰, 아이폰과 같은 모바일 디바이스에서도 통신할 수 있어야 하기 때문이다.

💡 REST 구성요소

  • 자원(Resource) : URI
    • 웹 서버의 자원은 각자 이름을 가지고 있다.
    • 따라서, 클라이언트는 이러한 이름을 통해 원하는 정보를 찾을 수 있다.
    • 이때 서버 자원의 이름을 URI라고 한다.
  • 행위(Verb) : HTTP Method
    • HTTP 프로토콜은 GET,POST,PUT,DELETE와 같은 메서드를 제공한다.
  • 표현(Representation of Resource)
    • 클라이언트가 자원의 상태(정보)에 대해 요청하면, 서버는 이에 적절한 응답을 보내야한다.
    • REST의 하나의 자원은 JSON, XML, TEXT, RSS 등 여러 형태의 응답으로 나타낼 수 있다.
    • 하지만, 보통 JSON 이나 XML을 통해 데이터를 주고 받는 것이 일반적이다.

 

📝 HTTP Method : [ POST ]

HTTP 메소드 중 POST는 요청을 처리하기 위해 사용자(클라이언트)로부터 특정 양식(form)의 "데이터를 암호화"하여 서버로 전송하는 방법이다.

서버는 POST 방식으로 전달 받은 데이터를 통해 특정 동작을 수행할 수 있다.
예로 로그인 예시를 보자.

<!-- login.html -->
<html>  
   <body>  
      <form action = "/login" method = "post">  
         <table>  
        <tr><td>아이디</td>  
        <td><input type ="text" name ="id"></td></tr>  
        <tr><td>비밀번호</td>  
        <td><input type ="password" name ="pass"></td></tr>  
        <tr><td><input type = "submit"></td></tr>  
    </table>  
      </form>  
   </body>  
</html>
# login.py

from flask import *  
# Flask 인스턴스 생성
app = Flask(__name__) 


@app.route('/')
def hello():
    return render_template('login.html')


# login 주소에서 POST 방식의 요청을 받았을 때
@app.route('/login',methods = ['POST'])  
def login():  
    id = request.form['id']  
    passwrd = request.form['pass'] 

    if id=="Elice" and passwrd=="Awesome!": 
        return "Welcome %s" % id  


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

[ 출처 : elice ]

이는, login.html 에서 "아이디"와 "비밀번호"를 입력하고, "버튼을 누르면" login.py 에서 이를 인식해서
"Elice" 이고, 비밀번호가 "Awesome!" 이면, "Welcome Elice" 라는 문구가 나타난다.

 

📝 HTTP Method : [ GET ]

GET 요청 또한 사용자(클라이언트)로부터 특정 양식(form)의 데이터를 서버로 전송하는 방법이다.

가장 큰 차이는 정보를 URL에 붙여서 보내게 되고, 즉, "데이터가 암호화되지 않는다는 점"이다.

앞선 로그인 예시를 통해 보자.

<!-- login.html -->
<html>  
   <body>  
      <form action = "/login" method = "get">  
         <table>  
        <tr><td>아이디</td>  
        <td><input type ="text" name ="id"></td></tr>  
        <tr><td>비밀번호</td>  
        <td><input type ="password" name ="pass"></td></tr>  
        <tr><td><input type = "submit"></td></tr>  
    </table>  
      </form>  
   </body>  
</html>
# login.py

from flask import *  
# Flask 인스턴스 생성
app = Flask(__name__)  


# login 주소에서 GET 방식의 요청을 받았을 때
# @app.route()에서 methods 인자의 기본 값은 GET으로 생략해서 작성해도 됩니다.
@app.route('/login',methods = ['GET'])  
def login():  
      id = request.args.get['id']  
      passwrd = request.args.get['pass']  
      if id=="Elice" and passwrd=="Awesome!": 
          return "Welcome %s" % id  


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

[ 출처 : elice ]

 

GET이 POST 방식과 가장 큰 차이점은 URL에 "https://localhost:8080/login?id=elice&pass=awesome" 으로 표현된다.

즉, 로그인 할 때, URL에 아이디와 비밀번호가 표기된다. ( = 데이터가 암호화가 되지 않는다. )
이는, 한편으로 정보보안을 유지할 수 없다는 것을 의미한다.

따라서, "로그인"과 같이 정보를 가려야할 때는 GET이 아닌 POST 방식을 사용하는 것이 맞다.

 

📝 HTTP - POST 예제

POST 요청은 눈에 파라미터가 보이는 GET요청과 달리 전달하려는 정보가 HTTP body에 포함되어 전달된다.

전달하려는 정보는 form data, json strings 등이 있다.

render_templates( ) 메소드 = Flask 에서 html 파일을 "랜더링" 하기 위해서 사용한다.
( 랜더링(Rendering) = 웹 브라우저 상의 화면을 표현하는 과정 )

POST로 전달받은 "값"은 request.form[ '변수명' ]을 사용하면 html의 form에서 해당 변수명에 만족 값을 사용가능

from flask import Flask
from flask import request
from flask import render_template

app = Flask(__name__)

@app.route('/')
def hello():
    return render_template('index.html')


@app.route("/post", methods=['POST'])
def post():
    #1번을 해보세요!
    value = request.form["input"]
    msg = "%s 님 환영합니다." % value
    return msg


if __name__ == '__main__':
    app.run()
<!-- 사용하는 html 파일들은, 반드시 templates 디렉터리 안에 있어야한다. !! -->
<!-- /templates/index.html -->


<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>HTML for python flask</title>
</head>

<body>
    <form action = "/post" method="post">
        <p>
            이름 : 
            <input type="text" name = "input">
        </p>
        <p>
            이름을 입력하고 제출버튼을 누르세요.<br>
            <input type = "submit" value = "제출" onclick = "alert('제출 완료!')" />
        </p>
    </form>
</body>
</html>

아이디 입력란에 아이디를 입력하고 제출하면, 제출완료 ! 와 동시에
post 방식으로, input에 "id님 환영합니다." 출력 

 

📝 HTTP - GET 예제

Flask 에서 GET 또는 POST로 전달받은 정보를 request 모듈을 사용하여 활용할 수 있다.

GET 방식의 경우 모든 파라미터를 URL로 보내 요청하는 방식이라고 했다.

request 모듈에는 GET 방식으로 URL의 인자를 'key = value' 형태로 전달했을 때, 다음 방식으로 활용한다.

  • 다음과 예시와 같은 주소를 입력했을 시, number의 값은 = 1 (https://주소.com/?key=1)
number = request.args.get('key`, 초기값)

초기값은 key 값으로 아무 값도 넘겨받지 못했을 때 활용되는 값이다. 이후에는 URL을 통해 '/?key=value' 형태로
key값을 전달받으면 해당 값을 사용한다.

여러개의 key와 값을 전달받으려면 다음 예시와 같이 '&' 기호를 입력하여 추가할 수 있다. 

  • key의 값은 1, value의 값은 2 (https://주소.com/?key=1&value=2)
from flask import Flask
from flask import request

app = Flask(__name__)

@app.route('/')     # Default는  HTTP methods = ['GET ']
def user_juso():
    temp1 = request.args.get("word1","Elice")   # GET 방식으로, request.args.get() 할때, 
    temp2 = request.args.get("word2","Hello")   # 주소에 값이 지정안되면 기본값은, 다음과 같음을 의미
    return temp1 + "<br>" + temp2

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

GET 방식 -> URL에 값을 전달할 경우
      GET -> URL 에 값이 전달되지 않을 경우        = default 값으로 대체

 

📝 HTTP - GET & POST 예제

GET과 POST를 동시에 사용해서 웹 페이지를 동작 시킬 수 있다.

method가 GET이면 이름을 입력받는 웹 페이지를 동작시키고, POST라면 입력 같은 값을 포함하는 문장을 출력한다.

<!-- templates/index2.html -->

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>HTML for python flask</title>
</head>

<body>
    <form action = "/" method="POST">
        <p>
            이름 :
            <input type="text" id = "input" name = "input">
        </p>
        <p>
            이름을 입력하고 제출버튼을 누르세요.
            <input type = "submit" value = "제출" onclick = "alert('제출 완료!')" />
        </p>
    </form>
</body>
from flask import Flask, render_template, request

app = Flask(__name__)

@app.route('/', methods=["GET","POST"]) # GET 또는 POST가 호출될 수 있다는 것
def post():
    if request.method == "POST":
        value = request.form["input"]   # index2.html가서 form태크를 보면 요소에 method = "POST" 일것이다.
        return f"{value}님 환영합니다."
    
    if request.method == "GET":
        return render_template("index2.html")

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

GET 
form 입력, 즉 POST로 데이터를 보내겠다.
POST

 

📝 API 와 End point가 무엇인가 ?

API프로그램들이 서로 상호작용하는 것을 도와주는 매체이다.

우리가 음식점에 갔을 때, 아래와 같이 행동한다. 점원은 손님에게 메뉴를 알려주고, 주방에 주문받은 요리를 요청한다.
그 다음 주방에서 완성된 요리를 손님에게 다시 전달한다.

  • 손님과 요리사는 "End Point"
  • 점원은 이 둘 사이에서 "API"

[ 출처 : elice ]

API는 손님(프로그램)이 주문할 수 있게 메뉴(명령 목록)를 정리하고, 주문(명령)을 받으면 요리사(응용프로그램)와 상호작용하여 요청된 메뉴(명령에 대한 값)를 전달한다.

 

💡 API의 역할은 무엇인가 ?

1. API는 서버와 데이터베이스에 대한 출입구 역할을 한다.

  • 데이터베이스에는 정보들이 저장된다. 
  • 따라서, 모든 사람들이 이 데이터베이스에 접근할 수 있으면 안된다.
  • API는 이를 방지하기 위해 우리가 가진 서버와 데이터베이스에 대한 출입구 역할을 하며, 허용된 사람들에게만 접근성을 부여해준다.

2. API는 프로그램과 기기가 원활하게 통신할 수 있도록 한다.

  • 우리가 흔히 알고 사용하고 있는 스마트폰 어플이나 프로그램과 기기가 데이터를 원활히 주고 받을 수 있도록 돕는 역할을 한다.

3. API는 모든 접속을 표준화한다.

  • API는 모든 접속을 표준화하기 때문에 기기나 운영체제 등과 상관없이 누구나 동일한 권한을 얻을 수 있다.

 

💡 API Testing

API Testing 은 API를 테스트하여 기능, 성능, 신뢰성, 보안 측면에서 기대를 충족하는지 확인하는 테스팅의 한 유형

완벽하게 작동하는 API만이 실제 애플리케이션에서 사용할 수 있다.
따라서, 정상적으로 완벽하게 작동하는지 테스트 해야한다.
API 테스트를 진행하게 되면 향후 특정 시점에서 발생할 수 있는 애플리케이션의 많은 문제점들을 해결할 수 있다.

[ 출처 : elice ]

728x90
반응형

📝 Flask

플라스크는 많은 사람이 "Micro Web Framework" 라고 부른다.
여기서 "Micro" = "프레임워크를 간결하게 유지하고 확장할 수 있도록 만들었다" 라는 의미

  • Micro : 가벼운 기능 제공, 가볍게 배우고 가볍게 사용할 수 있으며, 확장성이 넓다.
  • Framework : 이미 작성된 코드의 모임인 "라이브러리" 그 이상의 의미, 어플리케이션을 개발하기 위한 일정한 "뼈대"를 제공해주는 기술

간단한 웹 사이트, 간단한 API 서버를 만드는 데에 특화 되어있는 Python Web Framework 이다.
요즘은 클라우드 컴퓨팅의 발달로 Docker, Kubernetes와 접목해서, 소규모 컨테이너 단위로 기능 별 개발 후, 한꺼번에 배포하는 방식이나 배포 후 기능을 추가하는 식으로 자주 사용하고 있다.

💡 플라스크 장점

  • 가볍게 배울 수 있다 : HTML/CSS/JS 알고, python을 어느정도 알고있다면, 빠르게 배울 수 있다.
  • 가볍게 사용 가능하다. : 코드 몇 줄이면, 만들 수 있다.
  • 가볍게 배포할 수 있다. : pip을 사용하여 Flask를 다운받고 배포하면 끝이다.

💡 플라스크의 단점

  • Django에 비해서 자유도가 높으나, 제공해주는 기능이 덜 하다.
  • 복잡한 어플리케이션을 만들려고 할 때, 해야 할 것들이 많다.

Flask는 소규모의 어플리케이션을 빠르게 만들 수 있고, 배포 환경에 따라 대규모 어플리케이션의 기능 확장의 역할을 하기 쉬운 장점이 있다.
반면, Django는 대규모 어플리케이션을 빠르게 만들 수 있으며, 기본으로 제공해 주는 기능이 많다.

Flask Django
ORM 기능이 제공되지 않음 ORM 기능이 내장
짧은 코드로 웹 서버 구동가능 자동으로 관리자 화면 구성

ORM(Object Relational Mapping) : ORM은 DB와 OOP 언어 간의 호환되지 않는 데이터를 변환하는 프로그래밍 기법

 

📝 로컬에서 Simple Web Server띄우기 : Hello World !!

환경 : VS code, Python.exe 20.3.3 version 이상
(오류 발생시, 보통, 파이썬 실행파일 버젼이, 이전 버젼이어서 발생할 수 있으니 그럴 경우, 버젼 업그레이드 필요)

c:/python39/python.exe -m pip install --upgrade pip
c:/python39/python.exe -m pip install --upgrade pip --user (액세스 거부시)

성공 시, 아래와 같은 "Hello world!"를 보여주는 간단한, 플라스크 코드 작성

from flask import Flask  # 플라스크 import

app = Flask(__name__)   # app 이라는 이름의, flask앱을 하나 만들꺼야.

@app.route('/')             # 라우팅, '/'는 접속시, root 경로
def hello_World():          # '/'과 매칭되는 함수(root 경로일 시), 페이지에서 작동할 메소드
    return "Hello World!"

if __name__ == '__main__':  # 모듈 명이 "main"일 때만 실행하도록 조건문
    app.run()

127.0.0.1:5000(로컬) 에 출력된 Hello World

 

📝 Flask  HTTP 통신 : HTTP Methods

먼저 HTTP 개념을 모른다면 아래, 포스팅을 잠깐 읽고 오자. 

 

[Network] HTTP란 ?

📝 개요 우리 모두, 대부분 정보를 인터넷으로 확인한다. 모든 "웹 브라우저"에 있는 정보에 접근할 때는, "URL"을 통하여 접근한다. 반대로 생각하면, "URL을 모르는 정보에는 접근을 할 수 없다"

youngminieo1005.tistory.com

Flask는 HTTP 통신을 위해 다음과 같은 Methods를 제공한다.

Method 설명
GET 암호화되지 않은 형태의 데이터를 서버로 전송하는데 사용되는 가장 일반적인 방법
HEAD GET과 유사한 방법으로 Response Body를 포함지 않고 사용
POST 특정 양식의 데이터를 암호화하여 서버로 전송하는데 사용
PUT 특정 대상의 데이터를 갱신(Update)하는데 사용
DELETE URL에 지정된 대상을 삭제(DELETE)하는데 사용

 

📝 URL Routing 이란 ?

URL Routing : 서버에서 특정 URL에 접속했을 시, 보여줄 페이지를 정해주는 것

즉, 특정 URL을 일부 작업을 수행하기 위한 관련된 기능과 "Mapping"하는 데 사용된다.

https://page.com/home  # 홈화면을 보여주고
https://page.com/login # 로그인화면을 보여준다.

위에 예시같은 것이, URL Routing 이다.

💡 Flask에서 URL Mapping을 어떻게 할까 ?

Flask에서 URL Routing은 @app.route(' ')를 통해 수행한다.
또한, 여기서 @를 통해 선언하는 방식 = 데코레이터(decorator)라고 부른다.

from flask import Flask  # 플라스크 import

app = Flask(__name__)   # app 이라는 이름의, flask앱을 하나 만들꺼야.

@app.route('/')             # 라우팅, '/'는 접속시, root 경로
def home():          # '/'과 매칭되는 함수(root 경로일 시), 페이지에서 작동할 메소드
    return "This is Home page !!"

@app.route('/hello')        # "/hello" URL 접속 시 
def hello():
    return "Hello world !!"
if __name__ == '__main__':  # 모듈 명이 "main"일 때만 실행하도록 조건문
    app.run()

localhost 페이지
localhost/hello 페이지

 

📝 Variable Rules

플라스크에서는 route( ) 를 사용해서 url path의 값을 활용할 수 있다.
url path의 문자열, 정수, 서브경로를 활용할 수 있다.

  • 문자열은 사용할 변수명을 <변수명>으로 감싸주면 함수에서 전달받은 값을 활용할 수 있다.
  • 정수는 <int:변수명> 형태로 사용이 가능하다.
  • 서브경로는 <path:subpath> 형태로 사용이 가능하다.
from flask import Flask

app = Flask(__name__)

@app.route('/user/<username>')
def show_user_profile(username):
    return f"User {username}"

@app.route('/post/<int:post_id>')
def show_post(post_id):
    return f"Post {post_id}"

@app.route('/path/<path:subpath>')
def show_subpath(subpath):
    return f"Subpath {subpath}"

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

문자열  = <변수명>

 

정수 = <int:변수명>
서브경로 = <path:서브경로>

 

📝 데이터 반환하기 - jsonify( )

Flask 에서는 데이터를 json 파일 형식으로 데이터를 교환한다.

json 파일 형식은 웹 사이트 상에서 정보를 주고 받는 형식이다. Dictionary형태와 유사한 구조를 가진다.

Flask 에는 데이터를 json 형식으로 바꿔주는 jsonify( ) 메소드가 있다.

from flask import Flask, jsonify    # jsonify import

app = Flask(__name__)

@app.route('/')
def json():
    people = [
        {'name' : 'natto' , 'birth-year' : 2020},
        {'name' : 'apple' , 'birth-year' : 2021},
        {'name' : 'banana' , 'birth-year' : 2022}
    ]
    return jsonify(people)

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

jsonify( ) 반환 = json형식

 

📝 URL 설계하기 - URL Building

웹 사이트의 기본 구조를 설계하고 사용자들이 웹 사이트에 접속하기 위해 URL 구조를 설계할 필요성이 있다.

만약 한 페이지에서 다른 페이지로 이동할 수 있도록 "링크"를 생성하려면 어떻게 해야 할까 ?

Flask 에서는 url_for( ) 메소드를 통해 이를 수행한다.

url_for( ) 메소드 : 특정 함수에 대한 url을 "동적"으로 구축하는 데 사용한다.
일반적으로 url 끝점에 이동할 함수 이름과 점(.)을 접두사로 붙이는 것처럼 사용할 수 있다.

from flask import Flask, redirect, url_for

app = Flask(__name__)

# 홈 페이지로 이동
@app.route('/')
def home():
    return "주소창에 /user/admin과 /admin <br> /user/student 와 /student를 입력해보세요."

# 관리자 페이지로 이동
@app.route('/admin')
def admin():
    return "관리자 페이지 입니다."

@app.route('/student')
def student():
    return "학생용 페이지 입니다."

# redirect() 는 "페이지에 다시 연결한다"는 뜻으로 마치 페이지를 "새로고침" 한 것과 같은 동작한다.
@app.route('/user/<name>')
def user(name):
    # 전달 받은 name이 'admin'이라면 ?
    if name == 'admin':
        return redirect(url_for('admin'))
    
    # 전달 받은 name이 'student' 라면 ?
    if name == 'student':
        return redirect(url_for('student'))


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

/admin = /user/admin 같은 페이지를 보여준다.
/student = /user/studnet 같은 페이지를 보여준다.

다만, 차이는 터미널에서 볼 수 있듯이, "HTTP status code" 인 것 같다.

위에, HTTP 포스팅에서 설명했듯이

300 = "리다이렉트" , 200 = "성공" 을 의미한다.
두 경우 모두, GET Method를 사용한것은 공통점이다.

728x90
반응형

+ Recent posts