Menambah endpoint#
Fitur baru disediakan lewat REST API dengan menambah endpoint. Contohnya POST /summaries yang merangkum teks. Langkahnya mengikuti jalur yang sama dengan endpoint bawaan: use case, controller, router, lalu pendaftaran.
Sebelum mulai: kamu mengenal pembagian layer di proyek. Penjelasannya ada di Perjalanan sebuah request.
Langkah-langkah#
-
Tulis use case di layer application. Use case memuat aturan fiturnya dan menerima dependensinya lewat konstruktor:
src/application/usecases/summarize.pyfrom langchain.messages import HumanMessage from src.domain.exceptions import EmptyMessageError class SummarizeUseCase: def __init__(self, llm) -> None: self._llm = llm def execute(self, text: str) -> str: if not text.strip(): raise EmptyMessageError() prompt = f"Summarize in one paragraph:\n\n{text}" reply = self._llm.invoke([HumanMessage(content=prompt)]) return str(reply.text) -
Tulis controller. Controller memuat model request dan respons, fungsi yang merakit use case, dan handler:
src/interface/http/controllers/summary_controller.pyfrom functools import lru_cache from pydantic import BaseModel, Field from src.application.usecases.summarize import SummarizeUseCase from src.infrastructure.AI.llm.openai import get_llm_model class SummaryRequest(BaseModel): text: str = Field(min_length=1) class SummaryResponse(BaseModel): summary: str @lru_cache def get_summarize_usecase() -> SummarizeUseCase: return SummarizeUseCase(get_llm_model()) def create(request: SummaryRequest, usecase: SummarizeUseCase) -> SummaryResponse: return SummaryResponse(summary=usecase.execute(request.text)) -
Tulis router. Router menghubungkan path ke handler dan meminta FastAPI menyediakan use case-nya:
src/interface/http/routers/summaries.pyfrom fastapi import APIRouter, Depends from src.application.usecases.summarize import SummarizeUseCase from src.interface.http.controllers import summary_controller from src.interface.http.controllers.summary_controller import ( SummaryRequest, SummaryResponse, ) router = APIRouter(prefix="/summaries", tags=["summaries"]) @router.post("", response_model=SummaryResponse) def create( request: SummaryRequest, usecase: SummarizeUseCase = Depends(summary_controller.get_summarize_usecase), ) -> SummaryResponse: return summary_controller.create(request, usecase) -
Daftarkan router di entry point aplikasi. Tambahkan
summarieske baris impor router, lalu daftarkan router-nya: -
Mulai ulang server.
Melaporkan pelanggaran aturan bisnis#
Controller tidak perlu try/except. Lempar turunan DomainError dari use case, dan aplikasi mengubahnya menjadi HTTP 400 dengan body {"detail": "pesan"}. Untuk aturan baru, tambahkan kelas exception di src/domain/exceptions/__init__.py:
class TextTooLongError(DomainError):
"""Teks yang akan dirangkum melebihi batas."""
def __init__(self, limit: int) -> None:
super().__init__(f"Teks tidak boleh lebih dari {limit} karakter")
Memeriksa hasilnya#
Panggil endpoint barumu:
curl -X POST http://localhost:8000/summaries \
-H "Content-Type: application/json" \
-d "{\"text\": \"TEKS_YANG_DIRANGKUM\"}"
Ganti TEKS_YANG_DIRANGKUM dengan teksmu. Respons berisi field summary. Endpoint baru juga muncul di dokumentasi interaktif, di http://localhost:8000/docs.
Halaman terkait#
- Menguji agent untuk menguji endpoint dengan model palsu.
- HTTP API untuk kode status yang dipakai endpoint bawaan.
- Perjalanan sebuah request untuk alasan perakitan dependensi ditaruh di controller.