The previous implementation of jokes relied on the use of a lot of Maybe. While this made the creation of jokes and errors safe, it made it more difficult and less understandable when serializing and deserializing the objects. It also made it near impossible to extend without fiddling around with more Maybe fields.
This PR introduces the use of pydantic with an aim to improve readability, extendibility, and make it clearer where the data access is originating from. So instead of having to call Joke.create(response.json()) to get the combined joke and error, we now rely on separating the joke and the error, and using some initial validation before creating the objects.
@safe
def deserialize(response: Response) -> Joke | Error:
# First we get the response as a json object/dictionary
response_data = response.json()
# Then perform a basic check to see if the response data is useable.
# According the the Joke API documentation, the error field should be included
# in every response. This will also help us in determining which object to create.
is_error = response_data["error"]
# We finally return the data depending on whether the object is an error or not
return Joke(**response_data) if not is_error else Error(**response_data)
Note that the method is still wrapped with the safe decorator. This ensures that if any of the above code fails, it will not immediately raise an exception.
The previous implementation of jokes relied on the use of a lot of
Maybe
. While this made the creation of jokes and errors safe, it made it more difficult and less understandable when serializing and deserializing the objects. It also made it near impossible to extend without fiddling around with moreMaybe
fields.This PR introduces the use of pydantic with an aim to improve readability, extendibility, and make it clearer where the data access is originating from. So instead of having to call
Joke.create(response.json())
to get the combined joke and error, we now rely on separating the joke and the error, and using some initial validation before creating the objects.Note that the method is still wrapped with the
safe
decorator. This ensures that if any of the above code fails, it will not immediately raise an exception.