Чем больше кода, тем больше багов. Проект ogen генерирует код по OpenAPI спецификации, избавляя от сотен (или даже тысяч) строк скучного шаблонного кода на Go, который приходится писать вручную с риском допустить опечатку или ошибку. Генератор пишет клиент и сервер, а разработчику остаётся только реализовать интерфейс для сервера. И никаких interface{} и рефлексии, только строгая типизация и кодогенерация. Я расскажу, чем ogen отличается от существующих решений и почему стоит его попробовать. Генерируется строго-типизированный клиент и сервер, чем-то похоже на gRPC. Дополняется описанием из спецификации в комментариях. Для сервера генерируется интерфейс, который нужно имплементировать: Клиент генерируется аналогично: В ogen поддержаны maxLength, minLength, pattern (regex), minimum, maximum и другие валидаторы строк, массивов, объектов и чисел, для которых статически генерируются проверки на клиенте и сервере. Более того, эффективно проверяется, что обязательные поля заданы, а неизвестные (если не разрешены) не передаются: Поддержаны полностью, для них генерируются константы и проверяются значения и на клиенте, и на сервере: Тот же deepmap/oapi-codegen не проверяет значения enum-ов, только генерируя новый тип и константы. Там, где это возможно. В большинстве случаев, для опциональных (или nullable) полей в Go принято использовать указатели: Это пусть и привычный, но семантический костыль: В ogen это решается через генерацию обобщенных типов (дженерики пробовали использовать, но в этом случае они не подошли): С optional nullable deepmap/oapi-codegen не справился: А ogen сгенерировал дополнительный тип OptNilString: С помощью OptNilString можно выразить и отсутствие значения, и null, и значение пустой строки, и просто строку. Для массивов дополнительный тип можно не генерировать, изменяя семантику nil значения слайса в зависимости от схемы. Например, если поле optional, то nil будет означать отсутствие значения, а если nullable, то null. Для optional nullable поля уже придется сгенерировать обертку. Отказ от рефлексии достигается за счет того, что ogen не использует стандартный encoding/json с его ограничениями по скорости и возможностям, а генерирует статические энкодеры и декодеры: Это помогает сделать работу с json эффективнее и гибче, например, декодинг поля в несколько проходов для поддержки oneOf с дискриминатором (сначала парсится значение поля-дискриминатора, а потом уже значение целиком) и без (сначала обходятся все поля и тип выбирается по уникальным полям). В качестве библиотеки для работы с json используется go-faster/jx, сильно переработанный и оптимизированный форк jsoniter-а (может парсить почти гигабайт json логов в секунду на ядро, а писать — больше двух). Для того, чтобы не выбирать между echo и chi, ogen использует свой, эффективный статически сгенерированный роутер на основе radix tree: Статический роутер позволяет компилятору сделать множество оптимизаций: убрать лишние проверки на длину строки, сгенерировать эффективный код для сравнения префиксов вместо runtime.cmpstring, использовать оптимальный алгоритм поиска нужного case в switch вместо бинарного поиска, и т.д.  Всё это позволяет достичь скорости в несколько раз выше, чем у chi и echo (код бенчмарка): Возьмем что-то вроде такой тип-суммы: Её ogen сгенерирует следующим образом: И будет использовать дискриминатор сразу при парсинге: Тот же deepmap/oapi-codegen предполагает дополнительный ручной вызов (ну и на момент написания статьи, сгененированный им код сломан): Видимо, пользователь должен сам вызвать Discriminator, написать switch по возможным значениям и вызывать AsT() (T, error) в зависимости от значений. Более того, ogen может работать вообще без поля-дискриминатора, выбирая тип по уникальным полям: Если есть поле meow, то тип Cat, если bark — Dog, а если не нашли, то будет ошибка unable to detect sum type variant. Я не уверен, что знаю какой либо генератор для OpenAPI, который бы смог справиться с такой задачей, как минимум на Go. Подробные цветные сообщения об ошибках с контекстом и ссылкой на конкретное место: Основные преимущества ogen, которые я вижу: Руковожу разработкой