ORGPROG Telegram 386
REST API на максималках

Обсудили в клубе тему, что реально можно автоматизировать на сервере, если у вас уже есть openapi-схема и наговорили на целый пост. А если схемы нет, то причины ниже, могут убедить вас или ваших коллег генерировать схему не по обработчикам, а наоборот.

Для начала нужны генераторы кода на базе openapi-схемы, таких в каждой экосистема по несколько штук как минимум. Как они помогают?

На базовом уровне генераторы просто создают DTO, которые вы сами парсите и валидируете вручную:


router.POST("/loginJSON", func(c *gin.Context) {
var json Login // Login сгенерирован
if err := c.ShouldBindJSON(&json); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
})


Это уже хорошая помощь от наличия спеки, но все еще очень много рукопашки и отсутствие контроля, того, что обработчики написаны правильно. Потому что одно дело сгенерировать структуры, а другое правильно (в соответствии со спекой openapi) их использовать в нужных местах. В общем что еще хотелось бы:

⁃ Валидацию запроса по схеме
⁃ Биндинг JSON → объект
⁃ Проверку ответа и статусов
⁃ Соответствие маршрутов и сигнатур контроллеров контракту

Только в этом случае, мы получим 100% пользу от наличия openapi схемы с максимальной автоматизацией всей рутины.

На практике же очень часто проверка ответа сводится к тестам, где JSON просто парсят и изучают его внутреннюю структуру вручную: сравнивают поля, типы, значения. В лучшем случае подключают валидацию по JSON Schema в тестах. Это по сути всё — ручная работа и проверки только на этапе выполнения тестов, без статических гарантий, подсказок редактора и без встроенного контроля на уровне фреймворка.

Полная генерация

Такое возможно только в случае наличия генераторов кода, которые глубоко интегрированы с фреймворком и умеют навешивать всю эту механику автоматически. Как минимум - иметь адаптер к конкретному фреймворку. К счастью, это есть плюс-минус во всех популярных экосистемах, но другой вопрос - знаете ли вы об этом и используете ли.

Давайте для примера возьмем Java и Spring Boot, где подобные задачи решаются давно и хорошо. В Spring Boot обычно используют OpenAPI Generator - он по спецификации генерирует интерфейсы контроллеров и модели (DTO). Вот пример интерфейса, который он генерирует:


public interface LoginApi {

@PostMapping("/login")
ResponseEntity<LoginResponse> login(@Valid @RequestBody LoginRequest request);
}


⁃ LoginRequest / LoginResponse — сгенерированные модели (с аннотациями валидации).
@RequestBody - Jackson сам парсит JSON → объект.
@Valid — проверка по аннотациям из схемы (400/422 уедут в хендлер ошибок).

И конкретная реализация


@RestController
class LoginController implements LoginApi {

@Override
public ResponseEntity<LoginResponse> login(LoginRequest req) {
var user = new User().id("u1").email(req.getEmail());
return ResponseEntity.ok(new LoginResponse().token("jwt...").user(user));
}
}


В итоге маршрут, сигнатура и типы подтягиваются из OpenAPI, модели тоже сгенерены. Мы пишем только логику внутри метода.

p.s. В ваших проектах используется полная генерация или частичная?

Ссылки: Телеграм | Youtube | VK
🔥25👍156🥱3🤔2👀1



tgoop.com/orgprog/386
Create:
Last Update:

REST API на максималках

Обсудили в клубе тему, что реально можно автоматизировать на сервере, если у вас уже есть openapi-схема и наговорили на целый пост. А если схемы нет, то причины ниже, могут убедить вас или ваших коллег генерировать схему не по обработчикам, а наоборот.

Для начала нужны генераторы кода на базе openapi-схемы, таких в каждой экосистема по несколько штук как минимум. Как они помогают?

На базовом уровне генераторы просто создают DTO, которые вы сами парсите и валидируете вручную:


router.POST("/loginJSON", func(c *gin.Context) {
var json Login // Login сгенерирован
if err := c.ShouldBindJSON(&json); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
})


Это уже хорошая помощь от наличия спеки, но все еще очень много рукопашки и отсутствие контроля, того, что обработчики написаны правильно. Потому что одно дело сгенерировать структуры, а другое правильно (в соответствии со спекой openapi) их использовать в нужных местах. В общем что еще хотелось бы:

⁃ Валидацию запроса по схеме
⁃ Биндинг JSON → объект
⁃ Проверку ответа и статусов
⁃ Соответствие маршрутов и сигнатур контроллеров контракту

Только в этом случае, мы получим 100% пользу от наличия openapi схемы с максимальной автоматизацией всей рутины.

На практике же очень часто проверка ответа сводится к тестам, где JSON просто парсят и изучают его внутреннюю структуру вручную: сравнивают поля, типы, значения. В лучшем случае подключают валидацию по JSON Schema в тестах. Это по сути всё — ручная работа и проверки только на этапе выполнения тестов, без статических гарантий, подсказок редактора и без встроенного контроля на уровне фреймворка.

Полная генерация

Такое возможно только в случае наличия генераторов кода, которые глубоко интегрированы с фреймворком и умеют навешивать всю эту механику автоматически. Как минимум - иметь адаптер к конкретному фреймворку. К счастью, это есть плюс-минус во всех популярных экосистемах, но другой вопрос - знаете ли вы об этом и используете ли.

Давайте для примера возьмем Java и Spring Boot, где подобные задачи решаются давно и хорошо. В Spring Boot обычно используют OpenAPI Generator - он по спецификации генерирует интерфейсы контроллеров и модели (DTO). Вот пример интерфейса, который он генерирует:


public interface LoginApi {

@PostMapping("/login")
ResponseEntity<LoginResponse> login(@Valid @RequestBody LoginRequest request);
}


⁃ LoginRequest / LoginResponse — сгенерированные модели (с аннотациями валидации).
@RequestBody - Jackson сам парсит JSON → объект.
@Valid — проверка по аннотациям из схемы (400/422 уедут в хендлер ошибок).

И конкретная реализация


@RestController
class LoginController implements LoginApi {

@Override
public ResponseEntity<LoginResponse> login(LoginRequest req) {
var user = new User().id("u1").email(req.getEmail());
return ResponseEntity.ok(new LoginResponse().token("jwt...").user(user));
}
}


В итоге маршрут, сигнатура и типы подтягиваются из OpenAPI, модели тоже сгенерены. Мы пишем только логику внутри метода.

p.s. В ваших проектах используется полная генерация или частичная?

Ссылки: Телеграм | Youtube | VK

BY Организованное программирование | Кирилл Мокевнин




Share with your friend now:
tgoop.com/orgprog/386

View MORE
Open in Telegram


Telegram News

Date: |

As of Thursday, the SUCK Channel had 34,146 subscribers, with only one message dated August 28, 2020. It was an announcement stating that police had removed all posts on the channel because its content “contravenes the laws of Hong Kong.” The initiatives announced by Perekopsky include monitoring the content in groups. According to the executive, posts identified as lacking context or as containing false information will be flagged as a potential source of disinformation. The content is then forwarded to Telegram's fact-checking channels for analysis and subsequent publication of verified information. The channel also called on people to turn out for illegal assemblies and listed the things that participants should bring along with them, showing prior planning was in the works for riots. The messages also incited people to hurl toxic gas bombs at police and MTR stations, he added. It’s easy to create a Telegram channel via desktop app or mobile app (for Android and iOS): Concise
from us


Telegram Организованное программирование | Кирилл Мокевнин
FROM American