Найти в Дзене
Дед Мазай на Котлине

Spring Boot + Kotlin request body validation

Если для валидации входящих запросов в Spring Boot на Kotlin вы используете библиотеку spring-boot-starter-validation, то эта статья будет для вас полезна. Работа с библиотекой в Kotlin имеет одну особенность, вязанную с использованием non nullable Kotlin-типов. Рассмотрим тестовый проект. В контроллере есть 2 эндпоинта (2 функции). Один принимает запрос с полем nullable типа. Второй — принимает запрос с полем non nullable типа. Входящие параметры обеих функций помечены аннотацией @Valid. Поля обеих моделей запросов помечены аннотацией @NotBlank. Также у нас есть контроллер для перехвата и обработки ошибок валидации: Направим на основные два эндпоинта одинаковые запросы с полем name в JSON body, равным null, и сравним полученные ответы. От non-nullable эндпоинта мы получим вот такой ответ: Здесь мы видим код ошибки 400 и дублирующую этот код информацию в JSON body. Полезна для нас эта информация? Неочень. От nullable эндпоита мы получаим вот такой ответ: Здесь мы также видим код ответа

Если для валидации входящих запросов в Spring Boot на Kotlin вы используете библиотеку spring-boot-starter-validation, то эта статья будет для вас полезна.

Работа с библиотекой в Kotlin имеет одну особенность, вязанную с использованием non nullable Kotlin-типов. Рассмотрим тестовый проект.

-2

В контроллере есть 2 эндпоинта (2 функции). Один принимает запрос с полем nullable типа. Второй — принимает запрос с полем non nullable типа. Входящие параметры обеих функций помечены аннотацией @Valid. Поля обеих моделей запросов помечены аннотацией @NotBlank.

-3

Также у нас есть контроллер для перехвата и обработки ошибок валидации:

-4

Направим на основные два эндпоинта одинаковые запросы с полем name в JSON body, равным null, и сравним полученные ответы.

-5

От non-nullable эндпоинта мы получим вот такой ответ:

-6

Здесь мы видим код ошибки 400 и дублирующую этот код информацию в JSON body. Полезна для нас эта информация? Неочень.

От nullable эндпоита мы получаим вот такой ответ:

-7

Здесь мы также видим код ответа 400 и уже более полезную информацию в JSON body о том, почему приложение не приняло наш запрос.

Разница в работе non-nullable и nullable эндпоинтов заключается в том, что приложение сначала пытается распарсить JSON body, а уже после этого — провалидировать поля полученного объекта. Распарсить не получается, т. к. Kotlin не позволяет создать объект CreateNonNullableRequest (name = null).

Чтобы получить от non-nullable эндпоинта более понятное сообщение об ошибке, добавим в ErrorHandlerController функцию для обработки ошибок общего типа.

-8

Направим на non-nullable эндпоинт невалидный запрос. И получим вот такой ответ:

-9

В ответе мы увидим код ошибки 500 и сообщение об ошибке: "JSON parse error: Instantiation of [simple type, class ru.epatko.template.model.CreateNonNullableRequest] value failed for JSON property name due to missing (therefore NULL) value for creator parameter name which is a non-nullable type".

Хотя такой ответ и выглядит понятным для человека, но для другого приложения, направившего запрос на наш эндпоинт, он будет намного менее понятным, чем ответ, который возвращает nullable эндпоинт. Потребуется приложить дополнительные усилия, чтобы приложение могло распарсить такой ответ как "невалидный запрос" и правильно на него отреагировать.

Вывод: если хотите добавить больше согласованности и понятности в ваш API, используйте для валидации JSON body входящих запросов nullable Kotlin типы полей.

Весь код проекта выложен на GitHub