Our first DTO#
In this section we will create our first DTO by extending our script to include a DTO that will ensure we don’t expose the user’s email in the response.
1from __future__ import annotations
2
3from dataclasses import dataclass
4
5from litestar import Litestar, get
6from litestar.dto import DataclassDTO, DTOConfig
7
8
9@dataclass
10class Person:
11 name: str
12 age: int
13 email: str
14
15
16class ReadDTO(DataclassDTO[Person]):
17 config = DTOConfig(exclude={"email"})
18
19
20@get("/person/{name:str}", return_dto=ReadDTO, sync_to_thread=False)
21def get_person(name: str) -> Person:
22 # Your logic to retrieve the person goes here
23 # For demonstration purposes, a placeholder Person instance is returned
24 return Person(name=name, age=30, email=f"email_of_{name}@example.com")
25
26
27app = Litestar(route_handlers=[get_person])
Here we introduce a new DTO class (ReadDTO
) and configure it to exclude the Person.email
field. The route
handler is also instructed to use the DTO to handle the response.
Lets look at these changes in more detail. Firstly, we add two additional imports.
The DTOConfig
class is used to configure DTOs. In this case, we are using it to
exclude the email
field from the DTO, but there are many other configuration options available and we’ll cover most
of them in this tutorial.
The DataclassDTO
class is a factory class that specializes
in creating DTOs from dataclasses. It is also a Generic
class, which means that it accepts
a type parameter. When we provide a type parameter to a generic class it makes that class a specialized version of the
generic class. In this case, we create a DTO type that specializes in transferring data to and from instances of the
Person
class (DataclassDTO[Person]
).
Note
It is not necessary to subclass DataclassDTO
to create a specialized DTO type. For instance,
ReadDTO = DataclassDTO[Person]
also creates a valid, specialized DTO. However, subclassing DataclassDTO
allows us to add the configuration object, as well as specialize the type.
Finally, we instruct the route handler to use the DTO (return_dto=ReadDTO
) to transfer data from the handler
response.
Lets try it out, again visit http://localhost:8000/person/peter and you should see the following response:
That’s better, now we are not exposing the user’s email address!