본문 바로가기
Language/python

[FastAPI] 2. 라우팅

by _YUJIN_ 2023. 7. 14.

1. 용어

1.1. "라우팅"이란?

  • 클라이언트가 서버로 보내는 HTTP 요청을 처리하는 프로세스이다. 

1.2. "라우트"란?

  • HTTP 요청 메서드의 요청을 수락하고 선택적으로 인수를 받을 수 있도록 정의된다. 
  • 요청이 특정 라우트로 전달되면 애플리케이션은 라우트 처리기(route handler)가 요청을 처리하기전에 해당 라우트가 정의되어 있는지 확인한다. 

1.3. "라우트 처리기 (route handler)"란?

  • 서버로 전송된 요청을 처리하는 함수이다.
  • ex) 요청을 받아 데이터베이스에서 특정 데이터를 추출하는 함수 

1.4. "HTTP 요청 메서드"란?

  • HTTP 메서드 처리 유형을 정의하는 식별자이다. 
  • 표준 메서드에는 GET, POST, PUT, PATCH, DELETE등이 있다. 

2. 라우팅 예시

2023.07.14 - [Language/python] - [FastAPI] 1. 시작하기 

이전 발행글에서 보면, 단일 라우트 애플리케이션을 만들었다.
코드를 다시 요약해보면 ..

1. app 변수로 초기화한 FastAPI( ) 인스턴스를 사용해서 라우팅을 처리하고,

2. 터미널창에서 uvicorn 도구가 FastAPI( ) 인스턴스를 가리키도록 했다. 

 

이렇게 FastAPI( ) 인스턴스를 라우팅 작업에 사용할 수 있지만 단일 경로만 고려하는 경우처럼 일반적으로만 사용된다. 

고유한 함수를 처리하는 각각의 라우트가 FastAPI( ) 인스턴스를 사용하는 경우 애플리케이션은 한 번에 여러 라우트를 처리할 수 없다. 

uvicorn이 하나의 엔트리 포인트만 실행하기 때문이다. 

 

* 인스턴스 ??

1. 객체 지향 프로그래밍(OOP: Object-Oriented Programming)에서, 어떤 클래스에 속하는 각 객체(object)를 의미한다.

2. 일반적으로 실행 중인 임의의 프로세스, 클래스의 현재 생성된 오브젝트

 

 

* 객체 지향 프로그래밍(OOP: Object-Oriented Programming) ??

1. C언어같은 절차 지향적인 프로그래밍이 아닌 객체의 관점에서 프로그래밍을 하는 것. 

2. OOP는 객체를 기준으로 코드를 나누어 구현한다. 

 

* 엔트리 포인트 ??

1. 코드가 시작될 때 실행이 시작되는 파일 또는 함수를 의미한다. 

2. 프로그램이 시작하는 시점

 

그래서, 여러 함수를 사용하는 라우트 처리는 APIRouter 클래스를 사용하여 해결한다. 

2.2. APIRouter 클래스를 사용한 라우팅

  • APIRouter 클래스는 다중 라우팅을 위한 경로 처리 클래스이고, fastapi 패키지에 포함되어 있다. 
  • 이 클래스를 가지고 애플리케이션 라우팅과 로직을 독립적으로 구성하고 모듈화 할 수 있다. 
#-- 예시
from fastapi import APIRouter

router = APIRouter()

@router.get("/hello")
async def say_hello()-> dict:
    return {
    "message" : "hello"
    }

이전에 만든 fastapi 폴더에 todo.py 파일을 새로 만들어주고 아래 코드를 작성한다. 

#-- todo.py 파일 작성
from fastapi import APIRouter

todo_router = APIRouter()

todo_list = []

#-- todo 처리를 위해 두 개의 라우트 추가 
#-- 1. todo_list에 todo를 추가하는 POST 메서드
@todo_router.post("/todo")
async def add_todo(todo: dict)->dict:
    todo_list.append(todo)
    return {
    	"message":"Todo added successfully."
    }
    
#-- 2. 모든 todo 아이템을 todo_list에서 조회하는 GET 메서드
@todo_router.get("/todo")
async def retieve_todos()->dict:
    return{
        "todos":todo_list
    }

APIRouter 클래스는 FastAPI 클래스와 동일한 방식으로 작동하지만, uvicorn은 APIRouter( )인스턴스를 실행시킬 수 없다.

그래서, APIRouter 클래스를 정의한 라우트를 FastAPI( ) 인스턴스에 추가해줘야한다. 

  • todo 라우트를 외부로 공개하기 위해서 `include_router` 메서드를 사용할 수 있다. 

* include_router(router1, router2, router3, ...)

APIRouter 클래스로 정의한 라우틀르 메인 애플리케이션의 인스턴스로 추가 -> 이렇게 하면 라우트를 전체 애플리케이션에서 사용할 수 있다. 

#-- api.py 파일 추가 작성
from fastapi import FastAPI
from todo import todo_router  #- APIRouter 클래스를 정의한 라우트인 todo_router 불러오기

app = FastAPI()

@app.get("/")
async def welcome() -> dict:
    return {
        "message" : "Hello World"
        }

app.include_router(todo_router) #- FastAPI() 인스턴스에 todo_router 추가

2.2.1. 실행

이전과 똑같이 uvicorn 명령어를 사용해서 애플리케이션을 실행해준다. 

uvicorn api:app --port 8000 --reload

애플리케이션이 실행되면 애플리케이션 로그가 실시간으로 표시된다.

2.2.2. 실행 테스트

새로운 터미널 창을 열어서 curl 명령어로 애플리케이션이 제대로 실행되는지 테스트해 볼 수 있다. 

curl http://localhost:8000

todo 라우트가 제대로 실행되는지도 테스트 해볼 수 있다. 

curl -X 'GET' 'http://localhost:8000/todo' -H 'accept: application/json'

todo 라우트가 실행되는것을 확인했으면, 이제 POST 요청을 전달해서 아이템을 todo_list에 추가해보자.

curl -X 'POST' \
'http://localhost:8000/todo' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"id":1, 
"item":"First Todo is to finish this book!"
}'

위의 코드를 실행시키면 "{'message':'Todo added successfully'}"라는 응답이 콘솔에 표시되는 것을 볼 수 있다. 

그리고 다시 todo라우트를 실행시켜보면 todo_list 내용이 추가된 것도 확인해볼 수 있다. 

반응형