Добавление книги и её обложек через API

Создание Book и BookCover должно быть атомарным, иначе ошибка оставит частично созданную книгу. Также не меняйте входной data, валидируйте обложки и возвращайте созданную книгу.

Короткий ответ

Что ответить на собеседовании

Создание Book и BookCover должно быть атомарным, иначе ошибка оставит частично созданную книгу. Также не меняйте входной data, валидируйте обложки и возвращайте созданную книгу.

Подробный разбор

Ответ с пояснениями

Условие

При выполнении POST‑запроса для создания новой книги вызывается функция create_book, которая формирует запись в таблице Book, а затем создает связанные записи в таблице BookCover.

Требуется провести ревью кода: проверить корректность и надёжность процесса создания сущностей, обратить внимание на возможные проблемы с атомарностью операций, обработкой исключений и потенциальными оптимизациями.

def create_book(data: dict):
    cover_list: list[dict] = data.pop('covers')
    new_book = Book.objects.create(**data)
    for cover in cover_list:
        BookCover.objects.create(**cover, book_id=new_book.id)

Ответ

Создание Book и BookCover должно быть атомарным, иначе ошибка оставит частично созданную книгу. Также не меняйте входной data, валидируйте обложки и возвращайте созданную книгу.

Порядок действий: проверить данные, скопировать data, извлечь covers, открыть transaction.atomic(), создать книгу и обложки, вернуть книгу. book_id задаётся сервером и не должен приниматься внутри cover от клиента.

Не подавляйте IntegrityError внутри сломанной транзакции; обработайте исключение снаружи atomic и сформируйте понятную ошибку API. Для многочисленных обложек возможен bulk_create, если не нужны индивидуальные save и сигналы. Файлы во внешнем хранилище не откатываются вместе с БД. При повторе POST нужна отдельная идемпотентность, если дубли книг недопустимы.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее