9696 5 . [ Alembic Migrations] ( #55-alembic-migrations )
9797 6 . [ CRUD] ( #56-crud )
9898 7 . [ Routes] ( #57-routes )
99+ 1 . [ Paginated Responses] ( #571-paginated-responses )
99100 8 . [ Caching] ( #58-caching )
100101 9 . [ More Advanced Caching] ( #59-more-advanced-caching )
101102 10 . [ ARQ Job Queues] ( #510-arq-job-queues )
@@ -412,6 +413,7 @@ First, you may want to take a look at the project structure and understand what
412413 │ │ ├── __init__.py
413414 │ │ ├── dependencies.py # Defines dependencies that can be reused across the API endpoints.
414415 │ │ ├── exceptions.py # Contains custom exceptions for the API.
416+ │ │ ├── paginated.py # Provides utilities for paginated responses in APIs
415417 │ │ │
416418 │ │ └── v1 # Version 1 of the API.
417419 │ │ ├── __init__.py
@@ -690,10 +692,15 @@ from app.core.database import async_get_db
690692
691693router = fastapi.APIRouter(tags = [" entities" ])
692694
693- @router.get (" /entities" , response_model = List[EntityRead])
694- async def read_entities (db : Annotated[AsyncSession, Depends(async_get_db)]):
695- entities = await crud_entities.get_multi(db = db)
696- return entities
695+ @router.get (" /entities/{id} " , response_model = List[EntityRead])
696+ async def read_entities (
697+ request : Request,
698+ id : int ,
699+ db : Annotated[AsyncSession, Depends(async_get_db)]
700+ ):
701+ entity = await crud_entities.get(db = db, id = id )
702+
703+ return entity
697704
698705...
699706```
@@ -708,6 +715,71 @@ router = APIRouter(prefix="/v1") # this should be there already
708715router.include_router(entity_router)
709716```
710717
718+ #### 5.7.1 Paginated Responses
719+ With the ` get_multi ` method we get a python ` dict ` with full suport for pagination:
720+ ``` javascript
721+ {
722+ " data" : [
723+ {
724+ " id" : 4 ,
725+ " name" : " User Userson" ,
726+ " username" : " userson4" ,
727+ 728+ " profile_image_url" : " https://profileimageurl.com"
729+ },
730+ {
731+ " id" : 5 ,
732+ " name" : " User Userson" ,
733+ " username" : " userson5" ,
734+ 735+ " profile_image_url" : " https://profileimageurl.com"
736+ }
737+ ],
738+ " total_count" : 2 ,
739+ " has_more" : false ,
740+ " page" : 1 ,
741+ " items_per_page" : 10
742+ }
743+ ```
744+
745+ And in the endpoint, we can import from ` app/api/paginated ` the following functions and Pydantic Schema:
746+ ``` python
747+ from app.api.paginated import (
748+ PaginatedListResponse, # What you'll use as a response_model to validate
749+ paginated_response, # Creates a paginated response based on the parameters
750+ compute_offset # Calculate the offset for pagination ((page - 1) * items_per_page)
751+ )
752+ ```
753+
754+ Then let's create the endpoint:
755+ ``` python
756+ import fastapi
757+
758+ from app.schemas.entity imoport EntityRead
759+ ...
760+
761+ @router.get (" /entities" , response_model = PaginatedListResponse[EntityRead])
762+ async def read_entities (
763+ request : Request,
764+ db : Annotated[AsyncSession, Depends(async_get_db)],
765+ page : int = 1 ,
766+ items_per_page : int = 10
767+ ):
768+ entities_data = await crud_entity.get_multi(
769+ db = db,
770+ offset = compute_offset(page, items_per_page),
771+ limit = items_per_page,
772+ schema_to_select = UserRead,
773+ is_deleted = False
774+ )
775+
776+ return paginated_response(
777+ crud_data = entities_data,
778+ page = page,
779+ items_per_page = items_per_page
780+ )
781+ ```
782+
711783### 5.8 Caching
712784The ` cache ` decorator allows you to cache the results of FastAPI endpoint functions, enhancing response times and reducing the load on your application by storing and retrieving data in a cache.
713785
0 commit comments