Привет!
Внезапный "а знаете ли вы пост?".
Наверняка вы слышали, что при проектировании REST API необходимо отдавать предпочтение стандартизированный штукам, например для авторизации использовать заголовок Authentication.
Чего вы, возможно, не слышали (по крайней мере я не слышал до вчерашнего дня) - ответы на запросы с заголовком Authentication запрещено кэшировать по умолчанию. А если использовать доморошенные заголовки, то надо не забыть явно запретить кэширование ответов.
#http_api@ergonomic_code #rest_api@ergonomic_code #posts@ergonomic_code
Внезапный "а знаете ли вы пост?".
Наверняка вы слышали, что при проектировании REST API необходимо отдавать предпочтение стандартизированный штукам, например для авторизации использовать заголовок Authentication.
Чего вы, возможно, не слышали (по крайней мере я не слышал до вчерашнего дня) - ответы на запросы с заголовком Authentication запрещено кэшировать по умолчанию. А если использовать доморошенные заголовки, то надо не забыть явно запретить кэширование ответов.
#http_api@ergonomic_code #rest_api@ergonomic_code #posts@ergonomic_code
IETF HTTP Working Group Specifications
RFC7234
Hypertext Transfer Protocol (HTTP/1.1): Caching
Привет
Сегодня у нас рубрика "Мои факапы".
Есть у меня один проект, где флоу создания одной из сущностей такой:
1) непривилегированный пользователь создаёт сущность
2) привилегированный пользователь её одобряет или отклоняет
ну и плюс привилегированный пользователь может её редактировать в любой момент.
я уже подробностей дизайна не помню, но с одной стороны у меня вроде были какие-то трудности с проектированием урла для аппрува (хотя щяс ретроспективно не понимаю, что за трудности), а с другой стороны чёт захотелось поэкономить методы.
В итоге сейчас у нас есть метод PATCH /entity/{id}
который принимает сущность с 15 нуллабельными полями. используется двумя способами - либо присылаются все 15, либо 1 - approved
И есть метод POST /entity
С теми же 15 полями. но не нуллабельными.
И хз что с этим добром теперь делать.
Щяс я уже думаю, что надо было не выпендриваться, обновление делать через PUT, а аппрув через PATCH /entity/{id}/approved или POST /entity/{id}/(approve|reject)
А от PATCH-а сущностей держаться подальше до тех пор, пока требования к стенке не припрут - в языках со статической типизацией это боль
И заодно наткнулся на прикольную штуку JSON-P - когда мне придётся в следующий раз делать патч, я так пойду, а не через типизированную нуллабельную ДТОшку
#case@ergonomic_code #project_camp@ergonomic_code #http_api@ergonomic_code #rest_api@ergonomic_code #tools@ergonomic_code
Сегодня у нас рубрика "Мои факапы".
Есть у меня один проект, где флоу создания одной из сущностей такой:
1) непривилегированный пользователь создаёт сущность
2) привилегированный пользователь её одобряет или отклоняет
ну и плюс привилегированный пользователь может её редактировать в любой момент.
я уже подробностей дизайна не помню, но с одной стороны у меня вроде были какие-то трудности с проектированием урла для аппрува (хотя щяс ретроспективно не понимаю, что за трудности), а с другой стороны чёт захотелось поэкономить методы.
В итоге сейчас у нас есть метод PATCH /entity/{id}
который принимает сущность с 15 нуллабельными полями. используется двумя способами - либо присылаются все 15, либо 1 - approved
И есть метод POST /entity
С теми же 15 полями. но не нуллабельными.
И хз что с этим добром теперь делать.
Щяс я уже думаю, что надо было не выпендриваться, обновление делать через PUT, а аппрув через PATCH /entity/{id}/approved или POST /entity/{id}/(approve|reject)
А от PATCH-а сущностей держаться подальше до тех пор, пока требования к стенке не припрут - в языках со статической типизацией это боль
И заодно наткнулся на прикольную штуку JSON-P - когда мне придётся в следующий раз делать патч, я так пойду, а не через типизированную нуллабельную ДТОшку
#case@ergonomic_code #project_camp@ergonomic_code #http_api@ergonomic_code #rest_api@ergonomic_code #tools@ergonomic_code
Привет!
Зацените чё накапал я ненавижу и работать с АПИ в виде сваггера (оно почти всегда не работает полностью) и уш тем более писать его - пихать в код гору аннотаций для доков к сваггеру, где соотношение сигнал шут 1 к 2 - то ещё удовольствие.
И сам я предпочитаю писать доки на Spring Rest Docs - и собственно текст доков можно нормально писать, и примеры гарантированно рабочие. Но многие привыкли таки к сваггеру и хотят его. А с этим тулом, кажется, можно разом обоих зайцев убить.
#docs@ergonomic_code #spring@ergonomic_code #http_api@ergonomic_code #rest_api@ergonomic_code
Зацените чё накапал я ненавижу и работать с АПИ в виде сваггера (оно почти всегда не работает полностью) и уш тем более писать его - пихать в код гору аннотаций для доков к сваггеру, где соотношение сигнал шут 1 к 2 - то ещё удовольствие.
И сам я предпочитаю писать доки на Spring Rest Docs - и собственно текст доков можно нормально писать, и примеры гарантированно рабочие. Но многие привыкли таки к сваггеру и хотят его. А с этим тулом, кажется, можно разом обоих зайцев убить.
#docs@ergonomic_code #spring@ergonomic_code #http_api@ergonomic_code #rest_api@ergonomic_code
GitHub
GitHub - ePages-de/restdocs-api-spec: Adds API specification support to Spring REST Docs
Adds API specification support to Spring REST Docs - ePages-de/restdocs-api-spec
👍3
Привет!
Я тут вынашиваю страшный план - отказаться от REST-стиля в "бэке одного фронта".
Как я собираюсь это делать:
1) Ядро продолжать так же делать из подсистем-объектов
2) Вокруг ядра сделать слой app, где по конторллеру на каждую страницу/экран/вью
3) урлы будут вида /api/app/login-page/login, api/app/dashboard-page/get-init-data
В общем в некотором смысле вернуться к структуре из этого поста, но сервисы приложения смёржить с контроллерами. Ну либо к пакетированию по компонентам Брауна
Что надеюсь получить:
1) Упростить процесс проектирования. Я давно этим занимаюсь и прочитал пачку книг по РЕСТу, но всё равно буквально в каждом проекте вылазит какая-нибудь штука, над которой я долго грею голову
2) снизить сцепленность ядра. в моём текущем подходе зачастую в подсистему надо тащить зависимость на другую подсистему, только для того чтобы вытащить вложенную сущность для какой-нить админки
3) Повысить удобство для фронтендеров - у них постоянно возникают вопросы что откуда брать для данной конкретной страницы. Тут, надеюсь, не будет. Плюс в доках появится понятное место куда можно будет сиквенс диаграммы работы страницы воткнуть
4) Повысить производительность. Как засунуть в рест один запрос для формы ввода, который вернёт пачку справочников для выпадающего списка - я не очень понимаю. А в эту схему - очень понимаю
Что потеряю и как планирую нивелировать потери
1) идиоматичность. С РЕСТом в целом народ как-то уже разобрался, а тут опять какая-то непонятная хрень. Это я попробую нивелировать за счёт простоты, возможности перенести общие принципы проектирования и постами с описанием идеи и кейсов
2) универсальность. Новому клиенту может не подойти существующее АПИ. Для второго клиента можно будет завести свой набор методов, а для третьего уже спроектировать и прикрутить сверху REST апи
Пока не очень понимаю что делать с методами, которые нужны на разных страницах. Но есть несколько идей:
1) по факту дублировать эндпоинты для них с минимизацией дублирования кода через делегирование в Котлине (и кстати о Котлине - я последнее время работаю с .net и чёт прям устал от NullPointerException - хочу назад в налло-безопстность 😥)
2) оставить такие методы в ядре
3) завести понятие ui-компонента на бэке - урлы вида /api/app/image-component/load
Я пока ещё думаю на эту тему и не уверен, что пойду туда, но возможно в ближайшем времени опробую её на личном проекте. И если опробую - расскажу как впечатления:)
#http_api@ergonomic_code #rest_api@ergonomic_code #ergo_approach@ergonomic_code
Я тут вынашиваю страшный план - отказаться от REST-стиля в "бэке одного фронта".
Как я собираюсь это делать:
1) Ядро продолжать так же делать из подсистем-объектов
2) Вокруг ядра сделать слой app, где по конторллеру на каждую страницу/экран/вью
3) урлы будут вида /api/app/login-page/login, api/app/dashboard-page/get-init-data
В общем в некотором смысле вернуться к структуре из этого поста, но сервисы приложения смёржить с контроллерами. Ну либо к пакетированию по компонентам Брауна
Что надеюсь получить:
1) Упростить процесс проектирования. Я давно этим занимаюсь и прочитал пачку книг по РЕСТу, но всё равно буквально в каждом проекте вылазит какая-нибудь штука, над которой я долго грею голову
2) снизить сцепленность ядра. в моём текущем подходе зачастую в подсистему надо тащить зависимость на другую подсистему, только для того чтобы вытащить вложенную сущность для какой-нить админки
3) Повысить удобство для фронтендеров - у них постоянно возникают вопросы что откуда брать для данной конкретной страницы. Тут, надеюсь, не будет. Плюс в доках появится понятное место куда можно будет сиквенс диаграммы работы страницы воткнуть
4) Повысить производительность. Как засунуть в рест один запрос для формы ввода, который вернёт пачку справочников для выпадающего списка - я не очень понимаю. А в эту схему - очень понимаю
Что потеряю и как планирую нивелировать потери
1) идиоматичность. С РЕСТом в целом народ как-то уже разобрался, а тут опять какая-то непонятная хрень. Это я попробую нивелировать за счёт простоты, возможности перенести общие принципы проектирования и постами с описанием идеи и кейсов
2) универсальность. Новому клиенту может не подойти существующее АПИ. Для второго клиента можно будет завести свой набор методов, а для третьего уже спроектировать и прикрутить сверху REST апи
Пока не очень понимаю что делать с методами, которые нужны на разных страницах. Но есть несколько идей:
1) по факту дублировать эндпоинты для них с минимизацией дублирования кода через делегирование в Котлине (и кстати о Котлине - я последнее время работаю с .net и чёт прям устал от NullPointerException - хочу назад в налло-безопстность 😥)
2) оставить такие методы в ядре
3) завести понятие ui-компонента на бэке - урлы вида /api/app/image-component/load
Я пока ещё думаю на эту тему и не уверен, что пойду туда, но возможно в ближайшем времени опробую её на личном проекте. И если опробую - расскажу как впечатления:)
#http_api@ergonomic_code #rest_api@ergonomic_code #ergo_approach@ergonomic_code
Алексей Жидков
Структура эргономичных программ - Алексей Жидков
Описание основных структур эргономичной кодовой базы
👍1
Привет!
У нас тут на проекте случилась поучительная история про REST, плюс посмотрел
REST next level: Crafting domain-driven web APIs by Julien Topçu @ Spring I/O 2023 - по мотивам всего этого накатал очередной микропост - что-то я разошёлся в этом месяце:)
#talks@ergonomic_code #http_api@ergonomic_code #rest_api@ergonomic_code
У нас тут на проекте случилась поучительная история про REST, плюс посмотрел
REST next level: Crafting domain-driven web APIs by Julien Topçu @ Spring I/O 2023 - по мотивам всего этого накатал очередной микропост - что-то я разошёлся в этом месяце:)
#talks@ergonomic_code #http_api@ergonomic_code #rest_api@ergonomic_code
YouTube
REST next level: Crafting domain-driven web APIs by Julien Topçu @ Spring I/O 2023
Spring I/O 2023 - Barcelona, 18-19 May
Slides: https://slides.com/julientopcu/rest-next-level-crafting-business-oriented-web-apis
GitHub repo: https://gitlab.com/crafts-records/columbiad-express
You have just coded your business logic by applying the…
Slides: https://slides.com/julientopcu/rest-next-level-crafting-business-oriented-web-apis
GitHub repo: https://gitlab.com/crafts-records/columbiad-express
You have just coded your business logic by applying the…
Привет!
Я ещё почти два года назад назад начал думать в сторону того, что пути эндпоинтов REST/JSON-over-HTTP API надо нарезать исходя из UX-клиентов, а не сущностей/ресурсов.
То есть, допустим, у нас есть пользователи и три эндпоинта:
1. Залогиниться
2. Посмотреть собвтенные данные
3. Посмотреть данные любого юзера для админов
И раньше я делал сам и наблюдал буквально во всех проектах, которые видел, эти эндпоинты замапили бы на:
1. POST /users/login
2. GET /users/profile
3. GET /users/profiles/{id}
А сейчас я бы это зампаил так:
1. POST /public/login
2. GET /user/profile
3. GET /admin/profiles/{id}
И после того, как я отказался от объектно-ориентированной декомпозиции и актуализировался вопрос декомпозции слоя приложения - эта идея заиграла новыми красками - первичную декомпозицию слоя приложения можно делать по UX-ам - считай приложениям
И, например, в TA я это так и сделал - если не считать вспомогательных пакетов infra и platform, в пакте app два подпакета:
1. public - "приложение"-точка входа, для регистрации и логина (по историческим причинам мапится на "/"...)
2. therapist - "приложение"-АРМ терапевта (мапится на "/therapist/")
Ещё есть "приложение"-сисадмина - Spring Boot Actuator (мапится на "/ops/**")
Такая схема, среди прочего ещё и существенно упрощает конфигурацию авторизации
Но это всё была прелюдия.
Я тут наткнулся на оригинальный пост про гексагональную архитектуру (ака порты и адаптеры), а там:
И я в этом тексте вижу те же самые приложения (в "левых"/основных портах у Кокбёрна), что и у себя.
В общем советую подумать в сторону того, сколько UX-ов есть у ваших (монолитных) бакендов и отражено ли это в вашей архитектуре
#design@ergonomic_code #rest_api@ergonomic_code #hexagonal_architecture@ergonomic_code #trainer_advisor@ergonomic_code
Я ещё почти два года назад назад начал думать в сторону того, что пути эндпоинтов REST/JSON-over-HTTP API надо нарезать исходя из UX-клиентов, а не сущностей/ресурсов.
То есть, допустим, у нас есть пользователи и три эндпоинта:
1. Залогиниться
2. Посмотреть собвтенные данные
3. Посмотреть данные любого юзера для админов
И раньше я делал сам и наблюдал буквально во всех проектах, которые видел, эти эндпоинты замапили бы на:
1. POST /users/login
2. GET /users/profile
3. GET /users/profiles/{id}
А сейчас я бы это зампаил так:
1. POST /public/login
2. GET /user/profile
3. GET /admin/profiles/{id}
И после того, как я отказался от объектно-ориентированной декомпозиции и актуализировался вопрос декомпозции слоя приложения - эта идея заиграла новыми красками - первичную декомпозицию слоя приложения можно делать по UX-ам - считай приложениям
И, например, в TA я это так и сделал - если не считать вспомогательных пакетов infra и platform, в пакте app два подпакета:
1. public - "приложение"-точка входа, для регистрации и логина (по историческим причинам мапится на "/"...)
2. therapist - "приложение"-АРМ терапевта (мапится на "/therapist/")
Ещё есть "приложение"-сисадмина - Spring Boot Actuator (мапится на "/ops/**")
Такая схема, среди прочего ещё и существенно упрощает конфигурацию авторизации
Но это всё была прелюдия.
Я тут наткнулся на оригинальный пост про гексагональную архитектуру (ака порты и адаптеры), а там:
What exactly a port is and isn’t is largely a matter of taste. At the one extreme, every use case could be given its own port, producing hundreds of ports for many applications. Alternatively, one could imagine merging all primary ports and all secondary ports so there are only two ports, a left side and a right side.
Neither extreme appears optimal.
The weather system described in the Known Uses has four natural ports: the weather feed, the administrator, the notified subscribers, the subscriber database. A coffee machine controller has four natural ports: the user, the database containing the recipes and prices, the dispensers, and the coin box. A hospital medication system might have three: one for the nurse, one for the prescription database, and one for the computer-controller medication dispensers.
It doesn’t appear that there is any particular damage in choosing the “wrong” number of ports, so that remains a matter of intuition. My selection tends to favor a small number, two, three or four ports, as described above and in the Known Uses.
Что именно является портом, а что нет, во многом является делом вкуса. С одной стороны, каждому юз-кейсу можно было бы присвоить свой собственный порт, создав сотни портов для множества приложений. В качестве альтернативы, можно было бы объединить все основные и все дополнительные порты, чтобы было только два порта, левый и правый.
Ни один из крайних вариантов не кажется оптимальным.
Система прогнозирования погоды, описанная в "Известных вариантах использования", имеет четыре естественных порта: канал прогноза погоды, администратор, уведомленные подписчики, база данных подписчиков. Контроллер кофемашины имеет четыре естественных порта: пользователь, база данных, содержащая рецепты и цены, дозаторы и ящик для монет. Больничная система выдачи лекарств может состоять из трех компонентов: один для медсестры, один для базы данных рецептов и один для диспенсеров лекарств с компьютерным управлением.
Похоже, что выбор “неправильного” количества портов не может нанести какой-то особый ущерб, так что это остается вопросом интуиции. Мой выбор, как правило, делается в пользу небольшого количества - двух, трех или четырех портов, как описано выше, и в известных случаях использования.
И я в этом тексте вижу те же самые приложения (в "левых"/основных портах у Кокбёрна), что и у себя.
В общем советую подумать в сторону того, сколько UX-ов есть у ваших (монолитных) бакендов и отражено ли это в вашей архитектуре
#design@ergonomic_code #rest_api@ergonomic_code #hexagonal_architecture@ergonomic_code #trainer_advisor@ergonomic_code
Telegram
Эргономичный код
Привет!
Я тут вынашиваю страшный план - отказаться от REST-стиля в "бэке одного фронта".
Как я собираюсь это делать:
1) Ядро продолжать так же делать из подсистем-объектов
2) Вокруг ядра сделать слой app, где по конторллеру на каждую страницу/экран/вью…
Я тут вынашиваю страшный план - отказаться от REST-стиля в "бэке одного фронта".
Как я собираюсь это делать:
1) Ядро продолжать так же делать из подсистем-объектов
2) Вокруг ядра сделать слой app, где по конторллеру на каждую страницу/экран/вью…
🔥4❤3👍2
Но не Jackson сегодня гвоздь программы.
Я накатал микропост о том как стремление улучшить HTTP API проекта (который был "готов" 1.5 недели назад) привело к улучшению дизайна его модели.
#http_api@ergonomic_code #rest_api@ergonomic_code #project_mariotte@ergonomic_code
Я накатал микропост о том как стремление улучшить HTTP API проекта (который был "готов" 1.5 недели назад) привело к улучшению дизайна его модели.
#http_api@ergonomic_code #rest_api@ergonomic_code #project_mariotte@ergonomic_code
Telegram
Эргономичный код
Привет!
Моя дилемма последней недели.
Я забацал небольшой демо-проект архитектуры, которую я использую в своих проектах и на этой базе написал пост с её описанием. Но не могу его опубликовать, потому что не могу придумать название и написать введение.
…
Моя дилемма последней недели.
Я забацал небольшой демо-проект архитектуры, которую я использую в своих проектах и на этой базе написал пост с её описанием. Но не могу его опубликовать, потому что не могу придумать название и написать введение.
…
👍4