Quick Start¶
Get your first HTTP and WebSocket endpoints running in 10 minutes.
Prerequisites
Make sure you've completed the Installation guide before proceeding.
Start the Application¶
The application should now be running at http://localhost:8000
Your First HTTP Endpoint¶
Let's create a simple HTTP endpoint to manage books.
1. Create the Model¶
Create app/models/book.py:
from sqlmodel import Field, SQLModel
class Book(SQLModel, table=True):
"""Book model."""
id: int | None = Field(default=None, primary_key=True)
title: str = Field(index=True)
author: str
isbn: str = Field(unique=True)
published_year: int
2. Create a Migration¶
3. Create the Repository¶
Create app/repositories/book_repository.py:
from app.models.book import Book
from app.repositories.base_repository import BaseRepository
class BookRepository(BaseRepository[Book]):
"""Repository for Book operations."""
pass
4. Create HTTP Endpoints¶
Create app/api/http/book.py:
from fastapi import APIRouter, Depends, HTTPException, status
from app.models.book import Book
from app.repositories.book_repository import BookRepository
from app.storage.db import async_session
router = APIRouter(prefix="/books", tags=["books"])
@router.post("/", response_model=Book, status_code=status.HTTP_201_CREATED)
async def create_book(book: Book):
"""Create a new book."""
async with async_session() as session:
repo = BookRepository(session)
return await repo.create(book)
@router.get("/", response_model=list[Book])
async def get_books():
"""Get all books."""
async with async_session() as session:
repo = BookRepository(session)
return await repo.get_all()
@router.get("/{book_id}", response_model=Book)
async def get_book(book_id: int):
"""Get book by ID."""
async with async_session() as session:
repo = BookRepository(session)
book = await repo.get_by_id(book_id)
if not book:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Book not found"
)
return book
5. Test the Endpoint¶
# Create a book
curl -X POST http://localhost:8000/books/ \
-H "Content-Type: application/json" \
-d '{
"title": "Clean Code",
"author": "Robert C. Martin",
"isbn": "978-0132350884",
"published_year": 2008
}'
# Get all books
curl http://localhost:8000/books/
# Get specific book
curl http://localhost:8000/books/1
Or visit the interactive API docs: http://localhost:8000/docs
Your First WebSocket Handler¶
Let's create a WebSocket handler to get books.
1. Add Package ID¶
Edit app/api/ws/constants.py:
class PkgID(IntEnum):
"""WebSocket package IDs."""
# ... existing handlers ...
GET_BOOKS = 100
CREATE_BOOK = 101
2. Create WebSocket Handler¶
Create app/api/ws/handlers/book.py:
from app.routing import pkg_router
from app.api.ws.constants import PkgID
from app.schemas.models import RequestModel, ResponseModel
from app.repositories.book_repository import BookRepository
from app.storage.db import async_session
@pkg_router.register(PkgID.GET_BOOKS)
async def get_books_handler(request: RequestModel) -> ResponseModel:
"""Get all books via WebSocket."""
async with async_session() as session:
repo = BookRepository(session)
books = await repo.get_all()
return ResponseModel.success(
request.pkg_id,
request.req_id,
data=[book.model_dump() for book in books]
)
@pkg_router.register(PkgID.CREATE_BOOK)
async def create_book_handler(request: RequestModel) -> ResponseModel:
"""Create a book via WebSocket."""
async with async_session() as session:
repo = BookRepository(session)
book_data = request.data
book = Book(**book_data)
created_book = await repo.create(book)
return ResponseModel.success(
request.pkg_id,
request.req_id,
data=created_book.model_dump()
)
3. Test WebSocket Handler¶
Using wscat or any WebSocket client:
# Install wscat (if needed)
npm install -g wscat
# Connect (replace TOKEN with actual JWT token from Keycloak)
wscat -c "ws://localhost:8000/web?access_token=YOUR_TOKEN"
# Send message
{"pkg_id": 100, "req_id": "test-001", "data": {}}
# Expected response
{
"pkg_id": 100,
"req_id": "test-001",
"status_code": 0,
"data": [...]
}
Add RBAC Permissions¶
Add role requirements directly to your handler decorators:
WebSocket Handler (app/api/ws/handlers/book_handler.py):
@pkg_router.register(
PkgID.GET_BOOKS,
json_schema=GetBooksModel,
roles=["get-books"] # Define required roles
)
async def get_books_handler(request: RequestModel) -> ResponseModel:
...
@pkg_router.register(
PkgID.CREATE_BOOK,
json_schema=CreateBookModel,
roles=["create-book", "admin"] # Multiple roles = user must have ALL
)
async def create_book_handler(request: RequestModel) -> ResponseModel:
...
HTTP Endpoint (app/api/http/book.py):
from app.dependencies.permissions import require_roles
@router.get(
"/books",
dependencies=[Depends(require_roles("get-books"))]
)
async def get_books():
...
@router.post(
"/books",
dependencies=[Depends(require_roles("create-book", "admin"))]
)
async def create_book(book: Book):
...
Now only users with appropriate roles can access these endpoints!
Next Steps¶
Congratulations! You've created your first HTTP and WebSocket endpoints. Next, learn about:
- Authentication - Secure your endpoints
- Rate Limiting - Protect against abuse
- Database Operations - Advanced database patterns
- Testing - Write tests for your endpoints