Skip to content

Commit

Permalink
docs: update dependencies section add real world example of dependenc…
Browse files Browse the repository at this point in the history
…y injection with Factory
  • Loading branch information
shakonord committed Sep 22, 2023
1 parent 38c1e06 commit f9cbf59
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 1 deletion.
29 changes: 28 additions & 1 deletion docs/dependencies.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ complexity you desire.
{!> ../docs_src/dependencies/more_complex.py !}
```

#### What is happenening
#### What is happening

The `number` is obtained from the `first_dependency` and passed to the `second_dependency` as a result and validates
and checks if the value is bigger or equal than 5 and that result `is_valid` is than passed to the main handler
Expand All @@ -48,3 +48,30 @@ and checks if the value is bigger or equal than 5 and that result `is_valid` is
{! ../docs_src/_shared/exceptions.md !}

The same is applied also to [exception handlers](./exception-handlers.md).

## More Real World example

Now let's imagine that we have some web application with one of the `views.py` as:

```python hl_lines="16"
{!> ../docs_src/dependencies/views.py !}
```

As you can notice the `user_dao` is injected automatically using appropriate level of dependency injection.

Let's see the `urls.py` and understand from where we got the `user_dao`:

```python hl_lines="14-16 32-34"
{!> ../docs_src/dependencies/urls.py !}
```

Here we use lambdas to create a callable from DAO instance.
> Read more about DAOs here: [Protocols](./protocols.md)
But we have cleaner version of this, we call it `Factory` method.

The Factory is a clean wrapper around any callable(yes classes usually are callables as well).
> No need to explicitly instantiate the class, just pass the name of the class to the Factory.
In conclusion, if your views/routes expects dependencies,
define them in upper level as described and they will appear automatically.
36 changes: 36 additions & 0 deletions docs_src/dependencies/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from esmerald import Factory, Include, Inject

route_patterns = [
Include(
"/api/v1",
routes=[
Include("/accounts", namespace="accounts.v1.urls"),
Include("/articles", namespace="articles.v1.urls"),
Include("/posts", namespace="posts.v1.urls"),
],
interceptors=[LoggingInterceptor], # Custom interceptor
dependencies={
"user_dao": Inject(lambda: UserDAO()),
"article_dao": Inject(lambda: ArticleDAO()),
"post_dao": Inject(lambda: PostDAO()),
},
)
]


route_patterns = [
Include(
"/api/v1",
routes=[
Include("/accounts", namespace="accounts.v1.urls"),
Include("/articles", namespace="articles.v1.urls"),
Include("/posts", namespace="posts.v1.urls"),
],
interceptors=[LoggingInterceptor], # Custom interceptor
dependencies={
"user_dao": Inject(Factory(UserDAO)),
"article_dao": Inject(Factory(ArticleDAO)),
"post_dao": Inject(Factory(PostDAO)),
},
)
]
21 changes: 21 additions & 0 deletions docs_src/dependencies/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from typing import List

from esmerald import get
from esmerald.openapi.datastructures import OpenAPIResponse


@get(
"/users",
tags=["User"],
description="List of all the users in the system",
summary="Lists all users",
responses={
200: OpenAPIResponse(model=[UserOut]),
400: OpenAPIResponse(model=Error, description="Bad response"),
},
)
async def users(user_dao: UserDAO) -> List[UserOut]:
"""
Lists all the users in the system.
"""
return await user_dao.get_all()

0 comments on commit f9cbf59

Please sign in to comment.