Query Parameters¶
When you declare other function parameters that are not part of the path parameters, they are automatically interpreted as "query" parameters.
# project_name/apps/items/controllers.py
from ellar.common import get, Controller, ControllerBase
fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]
@Controller
class ItemsController(ControllerBase):
@get('/weapons')
def list_weapons(self, limit: int = 10, offset: int = 0):
return fake_items_db[offset: offset + limit]
To query this operation, you use a URL like:
http://localhost:8000/api/weapons?offset=0&limit=10
The same benefits that apply to path parameters also apply to query parameters:
- Editor support (obviously)
- Data "parsing"
- Data validation
- Automatic documentation
Note: if you do not annotate your arguments, they will be treated as str
types:
# project_name/apps/items/controllers.py
from ellar.common import get, Controller, ControllerBase
fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]
@Controller
class ItemsController(ControllerBase):
@get('/weapons')
def list_weapons(self, limit, offset):
assert type(limit) == str
assert type(offset) == str
return fake_items_db[offset: int(offset) + int(limit)]
Defaults¶
As query parameters are not a fixed part of a path, they are optional and can have default values:
# project_name/apps/items/controllers.py
from ellar.common import get, Controller, ControllerBase
fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]
@Controller
class ItemsController(ControllerBase):
@get('/weapons')
def list_weapons(self, limit: int = 10, offset: int = 0):
return fake_items_db[offset: offset + limit]
In the example above we set default values of offset=0
and limit=10
.
So, going to the URL:
http://localhost:8000/items/weapons
http://localhost:8000/items/weapons?offset=0&limit=10
http://localhost:8000/items/weapons?offset=20
the parameter values in your function will be:
offset=20
(because you set it in the URL)limit=10
(because that was the default value)
Required and optional parameters¶
You can declare required or optional GET parameters in the same way as declaring Python function arguments:
# project_name/apps/items/controllers.py
from ellar.common import get, Controller, ControllerBase
weapons = ["Ninjato", "Shuriken", "Katana", "Kama", "Kunai", "Naginata", "Yari"]
@Controller
class ItemsController(ControllerBase):
@get("/weapons/search")
def search_weapons(self, q: str, offset: int = 0):
results = [w for w in weapons if q in w.lower()]
print(q, results)
return results[offset: offset + 10]
In this case, Ellar will always validate that you pass the q
param in the GET, and the offset
param is an optional integer.
GET parameters type conversion¶
Let's declare multiple type arguments:
# project_name/apps/items/controllers.py
from ellar.common import get, Controller, ControllerBase
from datetime import date
@Controller
class ItemsController(ControllerBase):
@get("/example")
def example(self, s: str = None, b: bool = None, d: date = None, i: int = None):
return [s, b, d, i]
str
type is passed as is. For the bool
type, all the following:
http://localhost:8000/items/example?b=1
http://localhost:8000/items/example?b=True
http://localhost:8000/items/example?b=true
http://localhost:8000/items/example?b=on
http://localhost:8000/items/example?b=yes
b
with a bool
value of True
, otherwise as False
. Date can be both date string and integer (unix timestamp):
http://localhost:8000/items/example?d=1672286800
# same as 2022-12-29
http://localhost:8000/items/example?d=2022-12-29
Using Schema¶
You can also use Schema to encapsulate GET parameters:
# project_name/apps/items/controllers.py
from typing import List
from pydantic import Field
from ellar.common import Serializer, get, Controller, Query, ControllerBase
class Filters(Serializer):
limit: int = 100
offset: int = None
query: str = None
category__in: List[str] = Field(None, alias="categories")
@Controller
class ItemsController(ControllerBase):
@get('/query-as-schema')
def query_as_schema(self, filters:Query[Filters]):
return {"filters": filters.dict()}