반응형

Fast API 사용을 위한 서버 구축을 완료 했다면, 이제 서비스 구현을 해 나가야 겠죠?

가장 필요한것은 API들을 만들어 나가는 것인데요.

Web에서 현재 거의 표준이다시피 한 것이 REST API 일 것입니다.

REST API 를 Restfull 하게 설계 하기 위해서는 몇가지 알아 두어야 할 사항이 있습니다.

REST API 설계 레시피

 

1. CRUD - POST/GET/PUT/DELETE 에 맞춰서 설계한다.

2. RESOURE 정의 데이타 중심으로 한다.

 - api에 동사 사용하지 않는다 : http://server.com/get-items => GET http://server.com/items 

 - 소문자만 사용한다 : GET http://server.com/Items => GET http://server.com/items 

 - 단어와 단어 사이에는 "_"(underscore, 밑줄) 대신 "-"(dash, 중간선)을 사용한다. 

  GET http://server.com/shoping_items => GET http://server.com/shoping-items  

 

먼저 HTTP 의 request 종류와 용도를 알아두면 좋습니다.

 

 

HTTP request 와 CRUD

아마 REST API를 검색하면 많은 빈도수로 CRUD가 나올 것입니다.

 

  REST API example  (resource = item)
http://myserver.com/api/item
C
Create
POST
item 생성
POST http://myserver.com/api/item/12223 

  name:"hello",
  value:"1234"
}
R
Read
GET
item 읽기
GET http://myserver.com/api/item/12223 

U
Update
PUT/ PATCH
item 업데이트
PUT http://myserver.com/api/item/12223 

  name:"hello",
  value:"1234"
}
PATCH  http://myserver.com/api/item/12223 

  value:"1234"
}
D
Delete
DELETE
item 삭제
DELETE http://myserver.com/api/item/12223 

 

 

원래 DB 쪽에서 시작된 용어이긴 하지만 일반적인 API 설계시에도 잘 들어 맞습니다.

그래서 REST API 설계시에도 매우 유용한 개념이기 때문에 REST API 설계시 사용하기 시작했습니다.

 

 

 

Fast API로 REST API 설계하기

 

Fast API로 rest api의 형태를 잡기 위해서는 가장 먼저 알아놔야 할것이  rest api 파라미터(parameter)의 형태를 어떻게 가져갈 것인가 입니다.

 

경로 파라미터

url 기본 패스(path)로 정의 하는 형태입니다.

아래와 같이 items 가 api의 resource에 해당하는 파트입니다. 즉, items 에 접근하기 위한 api를 의미합니다. 따로 get-items 와 같이 동사를 붙이지 않죠. GET이라는 행위는 http request의 형식에 GET으로 정의 합니다.

 

GET http://myserver.com/items

 

Fast API로는 아래와 같이 구현 합니다.

from fastapi import FastAPI

app = FastAPI()


@app.get("/items")
async def get_item_counts():
    return {"count": 10}

Fast API로 api를 정의한 부분을 보니 , 간단하고 보기 편하죠?

 

그다음 좀더 확장해서 경로 파라메터에 변수를 포함해서  활용하는 방법입니다. 

패스에 변수를 포함시키는 형태는 이와 같습니다.

GET http://myserver.com/items/{item_id}

ex) GET http://myserver.com/items/10

items/10 은 여기서 10번 item 정보를 가져온다고 가정 하죠.

이를 fast API에서는 아래와 같이 표현합니다.

from fastapi import FastAPI

app = FastAPI()


@app.get("/items/{item_id}")
async def read_item(item_id):
    return {"item_id": item_id}

read_item() 이라는 함수에 item_id를 넣고, item_id를 입력받은 변수로 사용하면 됩니다.
실제 구현에서는 item_id에 해당 하는 item을 꺼내서 return 해주면 되겠죠?

 

아래의 user_id 처럼 주소 중간에도 추가가 가능합니다.

@app.get("/users/{user_id}items/{item_id}")
async def read_user_item(user_id, item_id):
    return {
    "user_id": user_id,
    "item_id": item_id
    }

 

형태를 봤을때 경로 파라메터는 아주 단순하죠? 좀더 복잡하고 다양한 형태의 입력을 받아야 하는 경우들이 인터넷 세상에는 많습니다.

 

복잡하고 많은 정보를 입력으로 받아야 하는 경우, 2가지 형태로 구현할 수 있습니다.

첫번째는 쿼리(URL query) 형태입니다.

 

쿼리(Query)

쿼리 형태는 사실 표현 형식에서 경로 형태에 파라메터가 추가되는 형태로 흔히 브라우져에서 주소 입력창에서 자주 보던 형태 일건데요.

아래와 같은 형식입니다.

POST http://myserver.com/items ?user_id="goodboy" & item_id="123"

 

이렇게 ? 뒤에 key-value 형태로 파라메터를 추가해서 전달하는 방식입니다.

python 함수 내에 parameter로 정의 하는 것 만으로도 쿼리 구현이 됩니다. (fast api에 잘 구현되어있어서 편하게 쓸수 있네요.)

@app.post("/items")
async def add_item(user_id:str, item_id:str):
    return {
        "result":"success",
        "item_id":"D1234-889X-XX",
        "price":"5000000",
    }

 

데이타의 형태가 복잡해지거나 로직이 복잡해질 수록 query 처리하기 힘들어 지는 경우들이 발생합니다.

그중 한가지 예로 클래스로 데이타를 묶고 클래스로 데이타를 전달받고 처리하면 편리해질 것입니다.

이때 클래스의 구조가 바뀌면 parameter 형태도 바뀌게 되서 찾아서 수정해야 할 부분도 많아지겠죠.

이런 불편을 덜 수 있는 형태가 Requst body 입니다.

 

Request Body

Requst body를 이용하면 클래스와 같은 데이타 묶음을 처리하기 쉽습니다.

 

코드 를 작성할때 아래와 같이 어떤  정보를 json 으로 다뤄야 할 경우, 다음과 같이 합니다.

fast api에서 이렇게 class 를 json object로 잘 다룰 수 있도록 Pydantic BaseModel 이 구현되어 있습니다.

 

Pydantic BaseModel

먼저 Pydantic모듈의 BaseModel을 import하여 Class를 구성한다.

 

from typing import Union, List, Optional
from fastapi import FastAPI, Query
from pydantic import BaseModel


class Item(BaseModel):
    name: str
    description: Union[str, None] = None
    price: float
    tax: Union[float, None] = None


@app.post("/items/{item_id}")
async def add_tree(item:Item):
    pick = itemTable[item]
    return {
        "result":"success",
        "item_name":pick.name,
        "price":pick.price,
    }

이렇게 Item이 모듈화 됨으로 해서 구현이나 관리가 훨씬 편리해지고 유연해 질 수 있습니다.

 

 

이정도를 기초로 익혀두면 자신의 서비스를 확장해 나가는데 도움이 될것 같습니다.

더 심오한 내용이나 복잡한 것들은 추가로 Fast API 사이트를 레퍼런스 삼아서 공부 해야 겠죠 ^^

 

1. NginX 와 Fast API 셋업은 여기를...

 

해피 코딩 ^^!!

 

 

참고자료.

https://juna-dev.tistory.com/7

 

06. Fast API, Request Body (POST, PUT) 받기

지금까지는 GET방식이기에 URL 및 Request Header로 값이 넘어왔다. 하지만 POST방식에서는 Request Body로 넘어오기에 이전가지의 방식으로는 데이터를 받을 수 없다. Request Body는 Pydantic Model을 이용하여

juna-dev.tistory.com

 

Fast API 튜토리얼

https://fastapi.tiangolo.com/ko/tutorial/

 

자습서 - 사용자 안내서 - 도입부 - FastAPI

자습서 - 사용자 안내서 - 도입부 이 자습서는 FastAPI의 대부분의 기능을 단계별로 사용하는 방법을 보여줍니다. 각 섹션은 이전 섹션을 기반해서 점진적으로 만들어 졌지만, 주제에 따라 다르게

fastapi.tiangolo.com

 

'NginX+FastAPI' 카테고리의 다른 글

[NginX+Fast API] 1. Nginx + gunicorn + fast api 설정하기  (0) 2022.11.10
반응형

어플리케이션 개발을 진행하다보면, 서비스 또는 서버가 있으면 더 멋진 프로젝트로 만들 수 있을것 같은 그런 아이디어들이 생길때가 있습니다.

 

하지만 항상 어떻게 만들지 고민들을 하게 되는데, 다행히도 요즘은 여러 블로그와 유투브들에서 다양한 기술들과 방법들을 가이드 하고 있습니다. 

저는 Ubuntu 18.04 에서 Nginx 와 FastAPI 로 셋업을 했습니다.

 

셋업을 위해 필요한 패키지(package)들는 다음과 같습니다.

 

  • python 3.7
  • nginx
  • fastapi
  • uvicorn
  • gunicorn

 

NginX 설정 하기

 

nginx 를 설치를 먼저 합니다.

 

$ sudo apt-get install nginx

NginX가 잘 동작하는지 실행해봅니다.

 

그다음, 이제 nginx 와 app을 연결하는 과정이 필요한데요.

아래와 같이 fast_api.conf 를 nginx 밑에 생성합니다.

$ /etc/nginx/sites-enabled/fast_api.conf

파일이 없을 것이니 아래와 같이 nano 나 기타 editor로 파일을 만듭니다.
$ sudo nano /etc/nginx/sites-enabled/fast_api.conf

 


fast_api.conf 파일을 아래와 같이 수정합니다.

server{
	listen 80;
	server_name 123.45.67.8;  #your public ip
	location / {
#		include proxy_params;
		proxy_pass http://127.0.0.1:8000;
	}
}

그리고 나서 nginx를 제 시작합니다.

$systemctl restart nginx.service

또는

$sudo systemctl restart nginx.service

 

나머지는 pyton pip를 이용해서 설치 해야 하기에 python 설치 이후에 진행합니다.

 

우선 python이 설치 또는 실행 환경이 셋업 되었는지 확인합니다.

 

$ python --version

아마 python 2.7, python 3.6, python 3.7 과 같이 다양한 버전들이 설치 되어있을 것입니다.

주로 python2.x 대 버전은 python 으로 python 3.x 대 버전은 python3 로 실행하게 될건데요.

 

제가 현재 셋업한 환경에서는 python3.7에서 잘 동작을 하는것 같습니다.

 

우분투에 python 이 여러개 설치 되어있다면, configuration 해서 default를 3.7로 해줘야 합니다.

만약 가상환경이나 docker를 사용한다면 이 부분은 고려하지 않아도 됩니다.

저는 ubuntu에 3.7 환경을 설정 하였습니다.

 

$ sudo apt-get install python3.7

$ update-alternatives --install /usr/bin/python python /usr/bin/python3.7 3       <--- 3 은 인덱스로 기존에 설치된것이 있어서 3번째 로 번호를 붙였습니다.

$ update-alternatives --config python
There are 3 choices for the alternative python (providing /usr/bin/python).


  Selection    Path                Priority   Status
------------------------------------------------------------
* 0            /usr/bin/python3.7   3         auto mode
  1            /usr/bin/python2.7   1         manual mode
  2            /usr/bin/python3.6   2         manual mode
  3            /usr/bin/python3.7   3         manual mode

이렇게 python 설치를 하고 나면 pip로 package들을 설치 합니다.

 

$ pip install fastapi
$ pip install uvicorn
$ pip install gunicorn

그리고 아래 sample code를 작성합니다.

~$ mkdir test
~$ nano ~/test/main.py

[main.py]

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def root():
    print("hello")
    return {"message":"Server v0.0-400"}

 

 

자 아래와 같이 테스트를 진행해봅니다.

~$ cd ~/test
~$ uvicorn main:app
INFO:     Started server process [4406]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)

이렇게 하면 서버가 동작하는 것을 볼수 있습니다.

browser 에서 http://127.0.0.1:8000 으로 접속을 시도해보면  {"message":"Server v0.0-400"} 이런 결과를 확인 할 수 있습니다.

만약 이상한 것이 나온다면, 뭔가 설정이 잘못된 것이겠죠?

 

 

app을  ubuntu service 등록 하기

app위에서 작성한 앱을 ubuntu(linux)  service 등록 해서 사용합니다.

linux 서비스로 등록 해서 사용하는 이유는 여러가지가 있겠지만,

app을 terminal에서 start 시키고 terminal을 종료 시키면 app 실행이 유지 되지 않는 것도 하나의 이슈이고,

service로 만들어두면 여러가지로 활용이 가능하기 때문입니다.

서버가 부팅되면 자동 실행한다든가 하는 기능을 만들기 쉬워지기도 하죠.

 

ubuntu 에 service daemon을 등록 및 실행하는 과정입니다.

mika 라는 서비스를 만들어 등록하려고 한다고 합시다.


/etc/systemd/system/mika.service    <- 이 위치에 서비스 파일을 만듭니다.

systemctl daemon-reload    <- daemon관리자를 reload해서 새로 만든 서비스 파일을 인식할 수 있도록 합니다.

# systemctl 이라는 명령을 이용하여 서비스를 enable / start/ stop 등의 상태 조절이 가능합니다.

systemctl enable mika  <- 서비스를 enable 합니다.
systemctl start mika  <- 서비스 스타트
systemctl stop mika <- 서비스 종료

 

자 여기까지 하면 nginx 와 fastapi 설정이 완료 되었습니다.

 

앞으로 서비스를 추가 확장을 하려면, REST API를 추가해 나가면 되겠죠?^^

 

2. REST API 설계 는 여기를...

 

그럼.. 해피 코딩!

 

 

 

 

아래는 참고 자료 입니다.

 

NginX + FastAPI

 

https://facerain.club/fastapi-nginx/

 

Nginx로 FastAPI 배포하기 (Feat. Gunicorn)

Nginx와 Gunicorn을 이용하여 FastAPI 서버를 배포하는 방법을 알아봅시다.

facerain.club

 

 

https://velog.io/@ddhyun93/FastAPI-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD-%EC%85%8B%ED%8C%85%EC%9C%BC%EB%A1%9C-%EB%B0%B0%EC%9A%B0%EB%8A%94-nginx%EC%99%80-%EC%9B%B9%EC%84%9C%EB%B2%84%EC%9D%98-%EA%B4%80%EA%B3%84

 

 

Nginx - unit. :어플리케이션 서버.

 

https://www.lesstif.com/system-admin/nginx-unit-application-server-118096054.html#nginxunit%EC%B0%A8%EC%84%B8%EB%8C%80applicationserver-application%EC%B6%94%EA%B0%80

 

nginx unit - 차세대 application server

nginx unit은 CentOS 용 ruby 모듈을 제공하지 않습니다.

www.lesstif.com

 

 

Nginx + fast api 셋업 영상

https://youtu.be/SgSnz7kW-Ko

 

'NginX+FastAPI' 카테고리의 다른 글

[NginX+Fast API] 2. REST API 설계  (0) 2022.11.17

+ Recent posts