Ответ
В FastAPI маршрутизация запросов на основе HTTP-метода (GET, POST, PUT и т.д.) выполняется с помощью специальных декораторов. Это основной и наиболее декларативный способ.
1. Основной способ: Декораторы методов
Каждому HTTP-методу соответствует свой декоратор (@app.get, @app.post, @app.put, @app.delete и т.д.), который связывает URL-путь с функцией-обработчиком.
from fastapi import FastAPI
app = FastAPI()
# Этот обработчик будет вызван только для GET-запросов к /items/
@app.get("/items/")
async def read_items():
return {"method": "GET"}
# Этот обработчик — только для POST-запросов к /items/
@app.post("/items/")
async def create_item():
return {"method": "POST"}
2. Получение метода в процессе выполнения
Если необходимо узнать метод внутри самой функции (например, для логирования или сложной логики), можно использовать зависимость Request.
from fastapi import FastAPI, Request
app = FastAPI()
@app.api_route("/some-path", methods=["GET", "POST"]) # Обрабатывает несколько методов
async def handle_request_dynamically(request: Request):
# request.method содержит строку с названием HTTP-метода, например, "GET"
if request.method == "POST":
# Логика для создания ресурса
return {"message": f"Handling a {request.method} request"}
# Логика по умолчанию для GET
return {"message": f"Handling a {request.method} request"}
Таким образом, FastAPI предоставляет как статический (декораторы), так и динамический (Request объект) способы работы с HTTP-методами.
Ответ 18+ 🔞
Так, слушай, смотри, как это всё работает, а то я тут вижу, у некоторых мозги уже набекрень поехали от этих HTTP-методов.
Вот смотри, в FastAPI, если тебе нужно, чтобы по одному и тому же пути, ну, скажем, /items/, один код работал на чтение (GET), а другой — на запись (POST), то делается это проще пареной репы. Не надо городить огород, блядь.
Первый способ, он же основной, он же правильный, он же — не выёбывайся
Просто вешаешь на свою функцию-обработчик нужный декоратор. Хочешь GET — @app.get. Хочешь POST — @app.post. Всё, пипец, вопрос закрыт. FastAPI сам разберётся, какую функцию когда вызывать.
from fastapi import FastAPI
app = FastAPI()
# Эта штука сработает ТОЛЬКО если кто-то припёрся с GET-запросом на /items/
@app.get("/items/")
async def read_items():
return {"method": "GET"}
# А эта — ТОЛЬКО если прилетел POST на тот же самый /items/
@app.post("/items/")
async def create_item():
return {"method": "POST"}
Вот и вся магия. Чисто, красиво, без всяких подвохов. FastAPI — он умный, он не перепутает.
Второй способ, если ты хитрая жопа и хочешь всё в одной кучке
Бывает же, ну, мало ли, захотелось одну функцию на все методы запилить. Для логирования там, или ещё какая извращенская логика. Ну что ж, можно и так. Берёшь объект Request и смотришь, какой метод пришёл.
from fastapi import FastAPI, Request
app = FastAPI()
# Обрати внимание на @app.api_route и параметр methods. Тут мы говорим: "Эй, функция, лови и GET, и POST!"
@app.api_route("/some-path", methods=["GET", "POST"])
async def handle_request_dynamically(request: Request):
# А внутри уже смотрим, что за метод нам подсунули
if request.method == "POST":
# Ну, значит, создаём что-то, ебать его в сраку
return {"message": f"Handling a {request.method} request"}
# А если не POST, то по умолчанию считаем, что GET (ну или другая логика)
return {"message": f"Handling a {request.method} request"}
Но, честно говоря, если нет реальной причины — не усложняй, ёпта. Первый способ и читается лучше, и поддерживается легче. Не будь тем самым чуваком, который из-за желания выглядеть умным нагородил такую дичь, что потом сам же и обосрётся, когда её чинить придётся.
Короче, выбор за тобой. Можно по-простому, а можно — с приключениями на свою жопу.