FastAPI ile Modern API Geliştirme: Başlangıçtan İleri Seviyeye
Günümüzde modern web uygulamaları ve servisler, hızlı, güvenilir ve ölçeklenebilir API’ler üzerine inşa edilmektedir. Python programlama dilinin popülaritesi ve kullanım alanlarının genişlemesiyle birlikte, API geliştirme araçları da önem kazanmıştır. İşte tam bu noktada FastAPI devreye giriyor. FastAPI, Python 3.6+ ile geliştirilen, yüksek performanslı, kullanımı kolay ve hızlı bir web framework’üdür. Bu makalede, FastAPI’nin temel prensiplerinden başlayarak, ileri seviye konulara kadar uzanan kapsamlı bir yolculuğa çıkacağız.
İçindekiler
- FastAPI Nedir?
- FastAPI Kurulumu ve Temel Yapılandırma
- İlk API Endpoint’inizi Oluşturma
- Veri Doğrulama ve Serileştirme: Pydantic Entegrasyonu
- Request Body ile Çalışma
- Path Parametreleri ve Query Parametreleri
- Dependency Injection (Bağımlılık Enjeksiyonu)
- Güvenlik: Kimlik Doğrulama ve Yetkilendirme
- Middleware Kullanımı
- FastAPI Uygulamalarını Test Etme
- Otomatik API Dokümantasyonu (Swagger UI)
- FastAPI Uygulamasını Dağıtma
- Sonuç
FastAPI Nedir?
FastAPI, Philippe Choppin tarafından geliştirilen ve açık kaynaklı bir projedir. Diğer web framework’lerine kıyasla (örneğin Flask veya Django REST framework), FastAPI’nin öne çıkan bazı özellikleri şunlardır:
- Hız: Starlette ve Pydantic gibi yüksek performanslı kütüphaneler üzerine inşa edilmiştir.
- Kolay Kullanım: Öğrenmesi ve kullanması kolay bir API’ye sahiptir.
- Az Kod: Tekrar eden kod miktarını azaltır.
- Veri Doğrulama: Pydantic sayesinde veri doğrulama işlemleri kolaylıkla yapılabilir.
- Otomatik Dokümantasyon: Swagger UI ve ReDoc gibi araçlar sayesinde API dokümantasyonu otomatik olarak oluşturulur.
- Asenkron Desteği: Asenkron programlama (async/await) desteği sunar.
FastAPI Kurulumu ve Temel Yapılandırma
FastAPI’yi kullanmaya başlamak için öncelikle Python’ın kurulu olduğundan emin olun. Ardından, aşağıdaki komutu kullanarak FastAPI ve Uvicorn’u (bir ASGI sunucusu) kurun:
pip install fastapi uvicorn
Uvicorn, FastAPI uygulamanızı çalıştırmak için kullanılan bir ASGI sunucusudur. Kurulum tamamlandıktan sonra, temel bir FastAPI uygulaması oluşturabilirsiniz:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def read_root():
return {"message": "Merhaba Dünya!"}
Bu kodu `main.py` adında bir dosyaya kaydedin ve aşağıdaki komutu kullanarak uygulamayı çalıştırın:
uvicorn main:app --reload
`–reload` parametresi, kodda yapılan değişikliklerin otomatik olarak yeniden yüklenmesini sağlar. Tarayıcınızda `http://127.0.0.1:8000` adresine giderek uygulamanızı görüntüleyebilirsiniz.
İlk API Endpoint’inizi Oluşturma
FastAPI’de bir endpoint oluşturmak için, `@app` dekoratörünü ve HTTP metodunu (GET, POST, PUT, DELETE vb.) kullanmanız gerekir. Örneğin, bir GET endpoint’i oluşturmak için:
from fastapi import FastAPI
app = FastAPI()
@app.get("/items/{item_id}")
async def read_item(item_id: int, q: str = None):
return {"item_id": item_id, "q": q}
Bu örnekte, `/items/{item_id}` endpoint’i oluşturulmuştur. `item_id` bir path parametresidir ve `q` ise bir query parametresidir. FastAPI, tip ipuçlarını kullanarak otomatik olarak veri doğrulama yapar. Örneğin, `item_id`’nin bir integer olması beklenir.
Veri Doğrulama ve Serileştirme: Pydantic Entegrasyonu
Pydantic, Python’da veri doğrulama ve serileştirme için kullanılan bir kütüphanedir. FastAPI, Pydantic ile mükemmel bir şekilde entegre olmuştur. Bir Pydantic modeli tanımlayarak, API endpoint’lerinizdeki verilerin doğru formatta olmasını sağlayabilirsiniz:
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str = None
price: float
tax: float = None
@app.post("/items/")
async def create_item(item: Item):
item_dict = item.dict()
if item.tax:
price_with_tax = item.price + item.tax
item_dict.update({"price_with_tax": price_with_tax})
return item_dict
Bu örnekte, `Item` adında bir Pydantic modeli tanımlanmıştır. `name`, `description`, `price` ve `tax` alanları bulunmaktadır. FastAPI, bu modeli kullanarak request body’deki verilerin doğru formatta olup olmadığını otomatik olarak doğrular.
Request Body ile Çalışma
POST, PUT ve PATCH gibi HTTP metodları genellikle request body ile veri gönderirler. FastAPI, request body’deki verileri kolayca alıp işleyebilir. Yukarıdaki örnekte, `create_item` endpoint’i, `Item` modelini kullanarak request body’deki verileri alır ve işler.
Path Parametreleri ve Query Parametreleri
Path parametreleri, endpoint URL’sinde yer alan değişkenlerdir. Query parametreleri ise, URL’nin sonuna eklenen anahtar-değer çiftleridir. FastAPI, hem path parametrelerini hem de query parametrelerini kolayca işleyebilir:
from fastapi import FastAPI
app = FastAPI()
@app.get("/users/{user_id}/items/{item_id}")
async def read_user_item(user_id: int, item_id: str, q: str = None, short: bool = False):
item = {"item_id": item_id, "owner_id": user_id}
if q:
item.update({"q": q})
if not short:
item.update(
{"description": "Bu, harika bir ürün."}
)
return item
Bu örnekte, `user_id` ve `item_id` path parametreleridir, `q` ve `short` ise query parametreleridir. FastAPI, veri tiplerini otomatik olarak dönüştürür ve doğrular.
Dependency Injection (Bağımlılık Enjeksiyonu)
Dependency Injection, bir nesnenin bağımlılıklarını dışarıdan almasıdır. FastAPI, bağımlılık enjeksiyonunu destekler ve bu sayede kodunuzu daha modüler ve test edilebilir hale getirebilirsiniz:
from typing import Optional
from fastapi import Depends, FastAPI, Query
app = FastAPI()
async def common_parameters(q: Optional[str] = Query(None, max_length=50), skip: int = 0, limit: int = 100):
return {"q": q, "skip": skip, "limit": limit}
@app.get("/items/")
async def read_items(commons: dict = Depends(common_parameters)):
return commons
@app.get("/users/")
async def read_users(commons: dict = Depends(common_parameters)):
return commons
Bu örnekte, `common_parameters` fonksiyonu, `q`, `skip` ve `limit` parametrelerini alır ve bir sözlük olarak döndürür. `read_items` ve `read_users` endpoint’leri, `Depends` kullanarak bu fonksiyonu çağırır ve sonuçları kullanır.
Güvenlik: Kimlik Doğrulama ve Yetkilendirme
API’lerin güvenliği büyük önem taşır. FastAPI, OAuth2, JWT (JSON Web Tokens) gibi kimlik doğrulama ve yetkilendirme yöntemlerini destekler. Örneğin, JWT ile kimlik doğrulama yapmak için:
from fastapi import Depends, FastAPI, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from datetime import datetime, timedelta
from typing import Optional
from jose import JWTError, jwt
SECRET_KEY = "YOUR_SECRET_KEY" # Güçlü bir anahtar kullanın
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30
app = FastAPI()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
async def authenticate_user(username: str, password: str) -> Optional[dict]:
# Burada kullanıcıyı veritabanında kontrol edin.
# Örnek olarak, sabit bir kullanıcı verisi kullanılıyor.
if username == "testuser" and password == "testpassword":
return {"username": username}
return None
def create_access_token(data: dict, expires_delta: Optional[timedelta] = None):
to_encode = data.copy()
if expires_delta:
expire = datetime.utcnow() + expires_delta
else:
expire = datetime.utcnow() + timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
to_encode.update({"exp": expire})
encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
return encoded_jwt
async def get_current_user(token: str = Depends(oauth2_scheme)):
credentials_exception = HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Kimlik doğrulama başarısız.",
headers={"WWW-Authenticate": "Bearer"},
)
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
username: str = payload.get("username")
if username is None:
raise credentials_exception
except JWTError:
raise credentials_exception
user = {"username": username}
if user is None:
raise credentials_exception
return user
@app.post("/token")
async def login(form_data: OAuth2PasswordRequestForm = Depends()):
user = await authenticate_user(form_data.username, form_data.password)
if not user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Yanlış kullanıcı adı veya şifre",
headers={"WWW-Authenticate": "Bearer"},
)
access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
access_token = create_access_token(data={"username": user["username"]}, expires_delta=access_token_expires)
return {"access_token": access_token, "token_type": "bearer"}
@app.get("/users/me/")
async def read_users_me(current_user: dict = Depends(get_current_user)):
return current_user
Bu örnek, basit bir JWT kimlik doğrulama örneğidir. Gerçek bir uygulamada, kullanıcı verilerini bir veritabanında saklamanız ve daha güvenli bir anahtar kullanmanız gerekir.
Middleware Kullanımı
Middleware, gelen ve giden request’leri işleyen fonksiyonlardır. FastAPI, middleware kullanımını destekler ve bu sayede request’leri loglama, yetkilendirme kontrolü gibi işlemleri kolayca yapabilirsiniz:
from fastapi import FastAPI, Request
from fastapi.responses import Response
import time
app = FastAPI()
@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
start_time = time.time()
response = await call_next(request)
process_time = time.time() - start_time
response.headers["X-Process-Time"] = str(process_time)
return response
@app.get("/")
async def read_root():
return {"message": "Merhaba Dünya!"}
Bu örnekte, `add_process_time_header` middleware’i, her request’in işlenme süresini hesaplar ve `X-Process-Time` header’ı olarak response’a ekler.
FastAPI Uygulamalarını Test Etme
FastAPI uygulamalarını test etmek için, `pytest` ve `httpx` gibi araçları kullanabilirsiniz:
from fastapi.testclient import TestClient
from .main import app # main.py dosyanızdan app örneğini içe aktarın
client = TestClient(app)
def test_read_main():
response = client.get("/")
assert response.status_code == 200
assert response.json() == {"message": "Merhaba Dünya!"}
def test_create_item():
response = client.post(
"/items/",
json={"name": "Foo", "description": "", "price": 50.2, "tax": 2.0},
)
assert response.status_code == 200
assert response.json() == {"name": "Foo", "description": "", "price": 50.2, "tax": 2.0}
Bu örnekte, `TestClient` kullanılarak API endpoint’lerine istekler gönderilir ve response’lar doğrulanır.
Otomatik API Dokümantasyonu (Swagger UI)
FastAPI, Swagger UI ve ReDoc gibi araçlar sayesinde API dokümantasyonunu otomatik olarak oluşturur. Uygulamanızı çalıştırdıktan sonra, `http://127.0.0.1:8000/docs` adresine giderek Swagger UI’ı görüntüleyebilirsiniz. `http://127.0.0.1:8000/redoc` adresinde ise ReDoc dokümantasyonunu görüntüleyebilirsiniz.
FastAPI Uygulamasını Dağıtma
FastAPI uygulamasını dağıtmak için, çeşitli platformları kullanabilirsiniz. Örneğin, Docker kullanarak bir konteyner oluşturabilir ve bu konteyneri bulut platformlarına (AWS, Google Cloud, Azure) veya sunucularınıza dağıtabilirsiniz. Ayrıca, Heroku, Render gibi platformlar da FastAPI uygulamalarını kolayca dağıtmanıza olanak tanır.
Sonuç
FastAPI, modern API geliştirme için güçlü ve kullanışlı bir araçtır. Hızlı performansı, kolay kullanımı, veri doğrulama özellikleri ve otomatik dokümantasyon desteği sayesinde, API geliştirme sürecini önemli ölçüde hızlandırır ve kolaylaştırır. Bu makalede, FastAPI’nin temel prensiplerinden başlayarak, ileri seviye konulara kadar birçok konuya değindik. Artık siz de FastAPI ile modern API’ler geliştirmeye başlayabilirsiniz. FastAPI ile Modern API geliştirme dünyasına hoş geldiniz!