Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
286 changes: 141 additions & 145 deletions README.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/advanced_user_guide.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Customisation
=============

Learn how to customise your listing service without losing any performance with FastAPI Listing ✨
How to customise your listing service without giving up any of the performance of a hand-written query.

.. toctree::
:maxdepth: 3
Expand Down
202 changes: 102 additions & 100 deletions docs/basics.rst

Large diffs are not rendered by default.

198 changes: 92 additions & 106 deletions docs/filters.rst

Large diffs are not rendered by default.

37 changes: 18 additions & 19 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,31 @@
Welcome to fastapi-listing documentation!
=========================================

FastAPI Listing is an advanced data listing library that works on top of `fastAPI <https://fastapi.tiangolo.com/lo/>`_
to reduce the efforts in writing and maintaining your listing APIs by providing
a highly extensible, decoupled and reusable interface.
FastAPI Listing is a data listing library that sits on top of `FastAPI <https://fastapi.tiangolo.com/lo/>`_
to reduce the effort of writing and maintaining listing APIs, through a small set of composable,
decoupled components rather than one large endpoint function.

**Component** based Plug & Play architecture allows you to write easy to use and more **quickly** readable block of code.
Inject dependencies or swap components as you write more and more complex logics.
Filtering, sorting, pagination, and query construction are each their own **component** with a well
defined contract. Compose the defaults for the common case, or swap any one of them out for a custom
implementation without touching the rest.

It ships with SQLAlchemy support out of the box, but the Filter/Sorter/Paginator/QueryStrategy contracts are
backend-agnostic (see the *Customising your listing query* guide) - a non-ORM ClickHouse backend ships as a
reference implementation proving the same abstraction works for raw parameterized SQL too, and the same
approach extends to other ORMs/database toolkits.
It ships with SQLAlchemy support out of the box, but the Filter/Sorter/Paginator/QueryStrategy contracts
are backend-agnostic (see :doc:`query`) - a non-ORM ClickHouse backend ships as a reference implementation
proving the same abstraction works for raw parameterized SQL too, and the same approach extends to other
ORMs or database toolkits.

Features
--------

* **Component Based Architecture**: Small collection of independent instructions. Easy to create and attach.
* **Maintenance**: Fast to code and maintain, Light weight components are easy to create in case of multiple development iteration/customisations.
* **Fewer Bugs**: Reduce the amount of bugs by always having single responsibility modules, Focus on one sub problem at a time to solve the bigger one.
* **Easy**: Designed to be easy to use and never having the need to extend core modules.
* **Short**: Minimize code duplication.
* **Filters**: A predefined set of filters. Create new one or extend existing ones. An approach Inspired by **django admin**. Allows you to write powerful robust and reusable filters.
* **Backport Compatibility**: Level up your existing listing APIs by using FastAPI Listing without changing any client site dependency utilizing adapters.
* **Anywhere Dao objects**: Dao object powered by sqlalchemy sessions are just an import away. Use them anywhere to interact with database.

Having some knowledge of design patterns such as strategy pattern, adapter pattern and solid principles could be a plus going forward in this documentation 📚️.
* **Component-based architecture** - independent, single-responsibility pieces that are easy to create, test, and attach.
* **Fewer bugs by construction** - each component does one thing, so a change in one rarely ripples into the others.
* **No core modules to extend** - customisation happens by writing new components, not by subclassing internals.
* **A predefined set of filters** - inspired by Django admin's approach to writing and maintaining filters; create your own alongside the built-ins.
* **Backward compatibility via adapters** - adapt FastAPI Listing to an existing client's query-param format without changing the client.
* **DAO objects usable anywhere** - import a registered DAO directly wherever you need database access, not just inside a listing endpoint.

Some familiarity with the strategy and adapter patterns, and with SOLID principles generally, will make
this documentation easier to follow, though it isn't required.

The manual
----------
Expand Down
30 changes: 12 additions & 18 deletions docs/paginator.rst
Original file line number Diff line number Diff line change
@@ -1,28 +1,22 @@


Customising Paginator Strategy
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

We have a default pagination class. Which handles slicing of our data into pages with variable size. The provided pagination ``class``
is simple and gets the work done. If you wanna write your own efficient paginating strategy for huge tables or any other use case
you could write one by extending existing base or abstract paginating strategy ``class``.

For example you may wanna implement a paginating strategy which works on range ids for huge tables or only `previous` `next` pagination strategy and avoid
any count query.

The default pagination strategy slices data into variable-sized pages and covers most cases. For a huge
table, or a use case the default doesn't fit, extend the base paginating strategy to write your own -
for example, a keyset/range-based strategy, or a "previous"/"next" style paginator that avoids a count
query entirely.

.. code-block:: python
:emphasize-lines: 3, 4

@loader.register()
class EmployeeListingService(ListingService):
paginate_strategy: str = "default_paginator"
default_page_size: int = 10 # default page size modify this to change default page size.

default_page_size: int = 10 # change to alter the default page size


Post-fetch business logic
-------------------------
--------------------------

Not everything belongs in the query. Filling in zero-value rows for missing time buckets, a tie-break
re-sort that can't be expressed in SQL, reshaping rows differently for CSV export than for the JSON
Expand All @@ -47,10 +41,10 @@ are assembled into the response. Do post-fetch business logic here, not by overr

.. _alias overview:

Why use alias
-------------
Why use an alias
-----------------

* Avoid giving away original column names at client level. A steps towards securing and maintaining abstraction at api level.
* Shorter alias names are light weight. payload looks more friendly.
* Saves a little bit of bandwidth by saving communicating some extra characters.
* save coding time with shorter keys.
* Avoids exposing real column names to the client - a small step toward keeping the API's abstraction boundary intact.
* Shorter aliases keep response payloads lighter.
* Saves a little bandwidth by not sending longer key names.
* Saves coding time with shorter keys.
Loading
Loading