Каких ошибок следует избегать, проектируя свое REST API

Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті.

Меня зовут Максим Ливак. Я Java-разработчик из команды ITOMYCH STUDIO. Нам приходилось работать со сложными проектами в финтех-сфере. Важнейший момент в этом направлении — легкость обмена данными между сервисами.

Вот почему я обожаю API: они позволяют обмениваться данными между проектами и продуктами. Рождаются комплексные приложения. Со стороны пользователя выглядят, как магия.

С API я работал довольно плотно, больше трёх лет разрабатывал Middleware API. Оно подразумевает интеграцию со многими внутренними API для получения необходимой информации о клиенте, вендорах банка или вызова нужных функций — создание платежа, вызов ОТП-проверки.

Со всеми этими API есть одна проблема: они не придерживаются одного стандарта. То есть каждый разработчик проектировал его как «подсказывало сердце». С подобными API сложно интегрироваться, ведь сразу не понятна задумка «автора». Один такой использовал буквы вместо имен полей (*в зале звучат нервные смешки*).

Что такое REST API

Прежде чем оценивать ошибки, определимся, что такое REST и какие правила следует соблюдать разработчику, проектируя такое API. По теории есть много статей, так что я сфокусируюсь на практической части.

Концепцию REST разработал в 2000 году Рой Филдинг (Roy Fielding), соавтор протокола HTTP. REST — шаблон проектирования, основанный на возможностях протокола HTTP. В этом вся прелесть: можно общаться между собой независимо от языка, фреймворка или платформы.

REST расшифровывается как REpresentational State Transfer, т. е. «передача репрезентативного состояния». По-человечески, это передача данных о текущем состоянии системы в довольно очевидной форме, которая «объясняет сама себя». С правильно спроектированным REST API легко работать даже при скудно оформленной документации.

Однако у REST есть свои преимущества и недостатки. Этот подход не в каждом случае полностью рабочий. У него есть отличные альтернативы: RPC, GraphQL, SOAP и другие. Не следует «впихивать» своё API в рамки REST или просто «прикрывать» его красивым названием, не придерживаясь никаких правил.

Концепции REST

Richardson’s Maturity Model (RMM) делит REST API на три уровня «зрелости»: Ресурс, HTTP и HATEOAS. К третьему уровню я отношусь неоднозначно, так как его сложно поддерживать. Деление на уровни помогает понять концепции, а еще его можно использовать как «пошаговую» инструкцию к рефакторингу API. Мне RMM поможет дать оценку «качества» API из ошибок в следующем разделе.

Уровень 1. Ресурс

Основное назначение REST — предоставлять данные, их еще называют ресурсами. Чтобы получить ресурс, используется его адрес URI. Вот несколько правил построения URI, чтобы предоставить удобный и понятный интерфейс для получения ресурсов:

Используйте только существительные. Мы оперируем ресурсами, а не действиями. Чтобы указать операцию, которую мы хотим провести над ресурсом, нужно использовать HTTP-методы.

Используйте множественное число. Ресурс является либо коллекцией GET /tickets, либо частью коллекции GET /tickets/123. Для удобства работы с коллекцией следует использовать множественное число.

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

Используйте фильтры, пагинацию, сортировку. Если нужно получить не все данные, а лишь выборку, то стоит использовать параметры запроса GET/tickets?start-date=2021-09-15&order=price,asc&page=2

Уровень 2. HTTP

Часто разработчики API «изобретают колесо», игнорируя возможности HTTP: смешивают данные, которые касаются ресурсов, и данные о самом запросе. Вот основные составляющие HTTP, в которых можно передавать информацию о запросе:

HTTP методы. Хотя REST фокусируется на ресурсе, а не на действии, нам нужно указывать способ взаимодействия с ресурсом. Для этого существуют HTTP методы: GET, POST, DELETE, PUT, PATCH, HEAD.

HTTP статусы. Это унифицированный способ определить тип ответа: успешный, ошибка из-за невалидных данных, ошибка из-за внутренних проблем сервера.

HTTP заголовки. Headers — это место, где передается вся дополнительная информация о запросе: ожидаемые типы запроса и ответа, авторизационный токен. Поддерживаются кастомные заголовки, что позволяет разработчику передавать данные, которым не место ни в URI, ни в параметрах запроса.

Уровень 3. HATEOAS

HATEOAS — последний шаг к настоящему REST. Он ослабляет связь между потребителем и API, потому что ему не нужно хранить URI. И меньше потребность в подробной документации, ведь информацию о доступных операциях можно получить напрямую из ресурса.

Общие рекомендации

REST предлагает много концепций, чтобы удачно проектировать API. От себя добавлю пару правил «хорошего тона», которых стоит придерживаться вне зависимости от архитектурного стиля.

Понятные переменные. Без них работа с API невозможна, разве что вы напрямую общаетесь с автором.

Версионность. Версионировать API можно в URI или в заголовках. Выбирайте любой способ, главное создавайте версионность. Она позволяет вносить изменение в систему самым безболезненным для потребителя путем.

Документация. Хорошая и подробная документация намного упростит жизнь потребителю, независимо от качества самого API.

Ошибки. Иногда HTTP-статусов не хватает, чтобы описать ошибку. Или нужно уточнить, в чём именно проблема. Для этого вся информация об ошибке передается в теле ответа. Сейчас нет конвенций «Как правильно отображать ошибку». Какой бы формат вы не выбрали, придерживайтесь его.

Безопасность. Есть много способов защитить данные API, но обязательный минимум — SSL/TLS и авторизация.

Кеш. Он снижает нагрузку на сервисы за вашим API и ускоряет работу.

Id запроса и ответа. Иногда нужно понять, что пошло не так, найти в логах нужный запрос, отследить цепочку вызовов. Для этого можно присваивать каждому запросу уникальный Id или принимать такой Id в заголовках запроса. Зависит от того, кому вы больше доверяете. Если у потребителя есть вопросы по работе вашего API, он предоставит вам Id интересующего запроса. А не будет объяснять на пальцах.

Stateless. В качественном API всё, что нужно для успешного ответа, передаётся в самом запросе. Оно не хранит никакой промежуточной информации между двумя запросами. Такие API проще масштабировать: любая сущность приложения может обработать любой запрос.

Ошибки при построении REST API

Какие распространенные ошибки могут совершить разработчики при написании REST API? Ниже несколько примеров. Приведенные API позиционируются именно как REST, так что и рассматривать я их буду на предмет нарушение правил этого шаблона проектирования.

Сервис адресов

Пример запроса:

GET /getAddressbyIdv4.json?id=123&lang=UA

Ошибки:

  • Использование глагола в пути к ресурсу.
  • Версия метода в имени ресурса.
  • В имени ресурса привязка к параметру «Id».
  • Расширение так же в имени ресурса.

Пример показательный: он нарушает правила первого уровня RMM. Хотя разработчики постарались полностью описать в имени ресурса назначение метода, на практике это ухудшает его читабельность. Поддерживать такой метод тяжело, поскольку любые изменения неочевидные и требуют доработок со стороны потребителя и владельца API: поднятие версии, добавление нового расширение.

Рефакторинг:

GET /v4/addresses?id=123&lang=UA
Content-Type: application/json

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

Адреса клиента

Пример запроса:

GET /getClientAddress.json?id=123&lang=UA

Ошибки:

  • Использование глагола в пути к ресурсу.
  • Нарушение иерархии ресурсов.
  • Отсутствие версионности.
  • Расширение в имени ресурса.

Метод похож на предыдущий. Однако из названия понятно, что важны не только адреса, но и связь с клиентом. В остальном набор ошибок похож.

Рефакторинг:

GET /clients/1234/addresses?lang=UA
Content-Type: application/json

В этот раз я указал id клиента не как параметр запроса, а добавил в путь ресурса. Так я выстроил логическую цепочку хранения ресурсов.

Получение юридических счетов

Пример запроса:

GET /allJuridicalAccounts?Id=123&session=security1&onlyOpen=Y&json=Y

Ошибки:

  • Сложное имя ресурса.
  • Передача авторизационной сессии как параметра запроса.
  • Нестандартный формат для логического параметра.

Пример тоже похож на предыдущий. Однако вместо глагола, в пути присутствует ненужная часть «all». Есть лишняя информация о запросе: авторизационная сессия и расширение передаются в параметре запросов.

Рефакторинг:

GET /clients/123/accounts/juridical?open=true
Authorization: security1
Content-Type: application/json

Всю информацию о запросе я вынес в HTTP-заголовки, чем улучшил читаемость метода. Также поменял формат логического параметра, что тоже улучшает читаемость и упрощает работу с методом. Пропала необходимость в дополнительном маппинге.

Получение информации по счёту

Пример запроса:

GET /getAccount?account=1234&session=security1&json=Y

Пример успешного ответа:

Status: 200
{
  "cc": "UAH",
  "iban": "UA1234",
  "err": "000000"
}

Пример неуспешного ответа:

Status: 200
{
  "err": "000001"
}

Ошибки:

  • Передача авторизационной сессии как параметра запроса.
  • Нестандартный формат логического параметра.
  • Непонятные сокращения в именах полей.
  • Нестандартный код ошибки.

Этот метод — часть того же API, что и предыдущий. Так что ошибки в запросе те же. Однако я хотел бы сфокусироваться на ответах этого метода. Его тело тяжело для понимания из-за сокращений в именах полей. Больше всего трудностей вызывает логика с ошибками: «000000» считается успешным ответом. Такую логику тяжело поддерживать, особенно если возвращаешься к ней через какое то время.

Рефакторинг:

GET /v1/accounts/1234
Authorization: security1
Content-Type: application/json

Пример успешного ответа:

Status: 200
{
  "currency": "UAH",
  "iban": "UA1234"
}

Пример неуспешного ответа:

Status: 500
{
  "errorMessage": "Internal Error"
}

Зачастую необходимо уточнить, что именно пошло не так: с помощью текста или внутреннего кода ошибки. Однако эффективнее использовать HTTP статусы, это упрощает работу с API.

Получение почты клиента

Пример запроса:

POST /rpblws_v1/rpbl/handle?format=json

session: security1
action: GETMAIL
{
  "Id": "123"
}

Ошибки:

  • Набор сокращений вместо имени ресурса.
  • Название операции в HTTP заголовке.
  • Использование POST для операции чтения.
  • Нестандартная передача авторизационной сессии.
  • Расширение как параметр запроса.

Один из моих «любимых» API. Идеальное пособие, как делать не нужно. Из названия метода абсолютно невозможно понять, что он делает. Подозреваю, это авторское сокращение и оно что-то говорит «избранным». Также у этого API проблема с URI: для всех методов он одинаковый, а название нужной операции передается в заголовках.

Рефакторинг:

GET /v1/clients/123/emails
Authorization: security1
Content-Type: application/json

В таком варианте смещается логика с операций на ресурсы. Улучшается читаемость, вся информация о ресурсе содержится в пути, а не разбросана по телу запроса и HTTP-заголовкам. Такой метод проще поддерживать: для передачи информации о запросе используются стандартные HTTP-заголовки.

Поиск получателя

Пример запроса:

POST /findRecipient

{
  "companyId": "1323",
  "serviceId": "1234A"
}

Пример неуспешного ответа:

Status: 230
{
  "errorMessage": "Missing lang property"
}

Ошибки:

  • Использование Post для операции чтения.
  • Использование нестандартных HTTP статусов для стандартной ситуации.

Здесь неправильно используется HTTP-метод. Обратите внимание на статус неуспешного ответа. Для стандартной валидационной ошибки используется собственный статус в интервале успешных ответов (200–299). Такой код усложняет обработку ответов от API: нужна дополнительная логика, которая отлавливает такого рода «кастомные» статусы.

Рефакторинг:

GET /v1/recipients?companyId=1323&serviceId=1234A

Пример неуспешного ответа:

Status: 400
{
  "errorMessage": "Missing lang property"
}

При таком подходе проще валидировать неуспешные ответы. Большинство библиотек для работы с HTTP сразу отлавливают статусы 4xx и 5xx и оборачивают их в удобную для работы ошибку.

Данные по клиенту

Пример запроса:

POST /all

{
  "r": [{
    "Operation": "getClientRelatives",
    "session": "security1",
    "i": {
      "ClientId": "1234"
    }
  }]
}

Ошибки:

  • Один метод для работы со всеми ресурсами.
  • Непонятные имена полей.
  • Авторизационная сессия в теле запроса.

Это API придерживается некого JSON-RPC подхода. Однако для такого рода информационных API отлично подходит REST. Кроме того, невозможно понять без документации, что обозначают имена полей «r» или «i».

Рефакторинг:

GET /v1/clients/1234/relatives
Authorization: security1
Content-Type: application/json

В сравнении с громоздким JSON, такой метод гораздо лучше читается. Видна связь между ресурсами. Такой вариант проще поддерживать: не нужно «собирать» тело запроса с кучей ненужных вложенностей.

Что вы об этом думаете?

Я хотел поделиться своими размышлениями об ошибках, которые допускают разработчики при проектировании REST API на примере конкретных API, с которыми мне приходилось работать. Очень надеюсь, что вам было полезно и кому-то статья поможет лучше понять концепции REST, для чего они нужны.

Если у вас есть примеры ошибок или же замечания по теме, пишите в комментариях — с удовольствием пообсуждаю.

👍НравитсяПонравилось22
В избранноеВ избранном13
LinkedIn

Лучшие комментарии пропустить

В багатьох прикладах в GET запитах вказано Content-Type: application/json. Думаю варто замінити на Accept: application/json

lang=UA — це також не стандартно. Стандартно це lang=uk.

Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Дякую за статтю. В принципі повторює те ж що наприклад описано в бест практис майкрософта. У мене питання:

Рефакторинг:

GET /v4/addresses?id=123&lang=UA
Content-Type: application/json

Рефакторинг:

GET /clients/1234/addresses?lang=UA Content-Type: application/json

Наскільки я розумію в цих обох ендпоінтах повертається один ресурс — адрес клієнта. Єдина різниця в тому, що другий ендпоінт фільтрує адреса повертаючи лише ті що під клієнта з айді 1234. Наскільки правильна така іерархія, коли в першому випадку не має вказано,що це адреса клієнтів, і чи дійсно не обійтись без дублювання ендпоінтів?

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

GET /v4/addresses?city=Kyiv
GET /v4/addresses?clientType=XXX

Второй — это домен работы с клиентами, и там я бы ожидал увидеть еще что-то типа

GET /clients/1234/emails
GET /clients/1234/accounts

і чи дійсно не обійтись без дублювання ендпоінтів?

Это, в общем случае, зависит от бизнес требований. Например, с точки зрения управления правами доступа, эндпойнт /v4/addresses может быть предназначен только для службы доставки, которым доступ на эндпойнт /v4/clients с информацией о клиентах закрыт

Більшість матеріалу скопійовано звідси

dou.ua/forums/topic/34550

А кто-то у себя на проекте городит HATEOAS казино ?

Как раз это полезная штука. Но она с Рест выглядит примерно как прикрутить парус на резиновой лодке, там где должны быть тяговые корабельные дизели.

Чи дійно потрібна ця штука, коли є Swagger auto generating docs?

Сваггер это немного не то. Сваггер это просто инфо о апи, документация.
HATEOAS это метадата, которая говорит о том, что может делать клиент.
Разница хорошо видна когда речь идет, например, о секурити. Один пользователь может получить что он имеет право вызывать 10 апи методов на этой странице, а другой пользователь на этой же странице может вызывать 50 методов. Сваггер и там и там вернет 50, тоесть полный список возможных апи методов без привязки к секурити.

Подумалось, а если ресурс можно удалять с 13:00 до 15:00? Для такого ресурса всегда отдавать эндпоинт для удаления или только в указанный промежуток времени?

Только с 13-00 до 15-00. HATEOAS аналогичен концепции гиперперессылок на http странице. Когда ты загружаешь страницу, с ней загружается список гиперссылок куда ты можешь перейти на этой странице (actions). Если акция действует с 13-00 до 15-00, то ссылка участвовать в акции показывается на сайте только в этот период.

Если рест это «нечто большее», может кто-то объяснить на пальцах как организовать взаимодействие между двумя процессами в Windows с использованием рест-архитектуры.

Как раз на Виндоуз есть подобная технология. Кто помнит называлась COM и DCOM. Суть ее была дернуть метод у обьекта в другой песочнице из своей песочницы. Ох и кровушки она попила у разработчиков. Потом пришли технологии вроде того же .NET и разработчики воскликнули, «бл* а что так можно было ??» Надеюсь Рест со временем отправится к праотцам вслед за COM, где ему и место.

Ох и кровушки она попила у разработчиков. Потом пришли технологии вроде того же .NET и разработчики воскликнули, «бл* а что так можно было ??»

ты не поверишь ))

Надеюсь Рест со временем отправится к праотцам вслед за COM, где ему и место.

ты путаешь чорта с чортом не особо разбираясь в сортах ))

Используйте фильтры, пагинацию, сортировку. Если нужно получить не все данные, а лишь выборку, то стоит использовать параметры запроса GET /tickets?start-date=2021-09-15&order=price,asc&page=2

«І знов двійка, Носенко.»
Пагинацию надо делать только keyset pagination

Пагинацию надо делать только keyset pagination

А теперь попробуйте доказать это миру ;)
Вот человек заходит на dou.ua, и что он видит? Offset pagination с URL типа dou.ua/forums/page/2. Какие-нибудь хабр, rsdn? То же самое.
Dou ещё и зачем-то экономить пытается (ну-тко попробуйте recent comments просмотреть дальше 10-й страницы... Волошин словно всё делает нарочно чтобы нельзя было даже в важных темах прочитать все комментарии).
И вот сидит такой разработчик и думает «отцы-монстры делают нумерацию страниц, а я что, рыжий?»

Пагинацию надо делать только keyset pagination

Я слышал легенду, что, если все эндпоинты какого-либо апи сделать POST, то интернет не выдержит и взорвется.

Еще прародитель ООП, Алан Кей, в своем ST завещал, что системы не должни дергать методы друг друга, а отсылать сообщения друг другу. С тех пор прошло 49 лет, но дремучая бугаевщина продолжает процветать. Чтож, небольшой мастер класс, для расширения сознания. Поставим в левом углу ринга всеми любимый Рест, а в правом крепыша но далеко не чемпиона Сервис Бас. Поехали.

1. Чтобы написать сервис который общается с 100500 другими сервисами, вам нужно всего один конфиг, один эндпоин. Выход на сервис бас. Чтобы написать сервис который общается с 100500 рест сервисами, вам нужно 100500 конфигов. Если какойто сервис сменил место жительства, ходим по этажам и опрашиваем всех кто его использовал.

2. Чтобы написать сервис с новым апи и при этом не поломать клиентов которые используют старый апи, нам нужно на сервис бас повесить два сервиса. Один обрабатывает сообщения в старом формате, другой в новом. На Рест сервисе нужно лепить свой велосипед с версией в урл или в хедере и жуткой развилкой в коде из кучи почти одинаковых классов.

3. Чтобы начинать профилировать ВСЕ сообщения которые ходят между 100500 сервисами, мы можем просто повесить листнер на сервис бас и читать все сообщения.
На Ресте нужно зайти в код каждого сервиса и написать свою прокладку, которая будет профилировать и логировать вызов

4. Чтобы горизонтально промасштабироваться, снять загрузку с одного сервиса, можно просто вместо одного сервиса повесить 10 одинаковых сервисов. Каждый из них будет харчеваться на сервис бас и выгребать по мере загрузки сообщения. На рест сервисе без костылей, это не сделать никак. Это тупое дерганье методов одного эндпоинта, одного сервиса.

5. Чтобы сделать отказоустойчивый сервис, например если Сервис А, отваливается вступает в работу Сервис Б, вешаются два сервиса на сервис бас с разными приоритетами обработки сообщений. На Рест это не решается никак.

6. Чтобы сделать асинхронный вызов, вы запустили джобу и ждете нотификейшин. На сервис бас это делается бай дезайн, на рест это делается через костыль колл бека или тормозной луп или никак.

7. Если сервис уходит в локдаун, сообщения могут скапливаться, перемещатся в дедлеттер и возвращаться обратно на сервис бас, для того чтобы возобновить прохождение распредлеенного процесса между 100500 сервисами. В Рест если запрос отвалился то все, давай досвидания.

Можно этот список продолжать долго.
Но смысл достаточно прост. REST как и любой другой RPC call — это очень примитивная технология, которая не годится, чтобы строить какие либо сложные системы. Это настойщий антипатерн проектирования и это было понятно почти 50 лет назад.

О, и ты здесь, я ждал когда ты свою глупость ляпнешь :)

О, и ты здесь, я ждал когда ты свою глупость ляпнешь :)

Хм,

дремучая бугаевщина продолжает процветать.

Мне таки интересно, кто ещё возразит :))

Я тут недавно слушал лекцию одного профессора. Так он сказал, что в отличии от других физиологических параметров человека, мозг наиболее изменчив. Мозг одного человека может отличатся от мозга другого человека в разных нервных областях в 40(!) раз. Что я могу сказать. Это означает, что какието области мозга у тебя вполне могут быть в десятки раз меньше чем у обычного человека. Ты генетически не можешь воспринимать некоторую информацию. Например если пострадало абстрактное мышление, то мой пост для тебя будет выглядеть не более чем фильетон из тв шоу, поскольку такой мозг не сможет представить как работают распредлеенные системы и прокрутить их на разные приимущества и недостатки.

Не понятно что ты хотел сказать. Естественно у РЕСТ сервисов в распределенной системе есть известные очевидные недостатки, которые точно так же известно и очевидно решаются через месседжинг.
Только все равно месседжинг должен поддерживать определенный контракт — условно тот же самый CRUD с пейлоадом запихивается в меседжи как и в случаи рест сервисов.
Ты мне лучше скажи, как ты обойдешься своим сервис басом без рест сервиса, если тебе нужно сделать публичное апи, которое потребляется неизвестным количеством клиентов?

Ты мне лучше скажи, как ты обойдешься своим сервис басом без рест сервиса, если тебе нужно сделать публичное апи, которое потребляется неизвестным количеством
клиентов?

1. Если количество клиентов неизвестно, то РЕСТ не лучший выбор. Что если этот Рест сервис просто задосят. Как быстро горизонтально промасштабироваться, сделать эластичной обработку нагрузки.
2. Сервис Бас как раз и задумывался как глобальный транспортный протокол. Тотже TCP/IP внезапно, это теже сообщения (пакеты) которые ходят асинхронно внутри сетей разного ранга. У сервис бас также как у любого публичного сервиса есть свой конекшин стринг, если ты в облаке. Подсоединяйся и отправляй сообщения.

Что если этот Рест сервис просто задосят. Как быстро горизонтально промасштабироваться, сделать эластичной обработку нагрузки.

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

У сервис бас также как у любого публичного сервиса есть свой конекшин стринг, если ты в облаке.

роли, авторизация, версионность?
Так или иначе публичный контракт потребует версионности, если этот контракт когда-либо будет меняться. А он будет. Поэтому версии нужно поддерживать с самого начала.

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

Для этого придумали костыль. Который решает некрасиво одну задачу, но остается еще куча открытый вопросов, которые описаны выше.

роли, авторизация, версионность?

А для Реста есть роли авторизация версионность из коробки ? У тебя в пакете для сервис бас упакованы креденшелы, если твой токен валиден твое сообщение обработают, если нет то нет.

Понятно, упоротость — видеть серебрянную пулю для любой проблемы.

Я нигде не писал про «любую проблему». Если вы пишите сайты визитки, простые круд приложения, у вас все происходит синхронно, с версиями проблем нет, сервисов мало. Ок. Используйте Рест.
Если хотите написать чтото более «живое», версионное, отказоустойчивое, которое держит нагрузку. То читайте вверху пункты и сразу понимайте, что между Рест и Сервис Бас разница примерно как между самокатом и автомобилем. Просто разные уровни.

системы не должни дергать методы друг друга, а отсылать сообщения друг другу.

И тут ты такой должен пояснить чем «отправка сообщения» отличается от «вызов метода» кроме как названия. Ты либо про асинхронность скажи (типа «асинхронного вызова» не существует, ха!), либо броадкаст нацепи (типа «сообщения» не друг другу, а видны всем подписавшимся).

По всем остальным пунктам имеет смысл дискусировать только после согласования терминов.

И тут ты такой должен пояснить чем «отправка сообщения» отличается от «вызов метода» кроме как названия.

Для этого тебе нужно ознакомится с термином: топология сетей.
В первой топологии, ты не знаешь кто твое сообщение обработает, когда обработает и когда придет ответ (Сервис Бас).
В второй топологии, ты стучишся на конкретный эндпоинт и ожидаешь немедленно ответ (Рест).
Разница огромна.

броадкаст

Поленился записать 8м пунктом. Конечно на топологии сетей вроде Сервис Бас возможна ситуация когда один сервис бродкастит сразу нескольким потребителям сообщения. На Рест такое естественно невозможно.

Отлично, супер, спасибо. Вот теперь можно тебя обсирать

1. Чтобы написать сервис который общается с 100500 другими сервисами, вам нужно всего один конфиг, один эндпоин. Выход на сервис бас. Чтобы написать сервис который общается с 100500 рест сервисами, вам нужно 100500 конфигов. Если какойто сервис сменил место жительства, ходим по этажам и опрашиваем всех кто его использовал.

Single point of failure, не масштабируемость, огромные затраты на траффик.

2. Чтобы написать сервис с новым апи и при этом не поломать клиентов которые используют старый апи, нам нужно на сервис бас повесить два сервиса. Один обрабатывает сообщения в старом формате, другой в новом. На Рест сервисе нужно лепить свой велосипед с версией в урл или в хедере и жуткой развилкой в коде из кучи почти одинаковых классов.

Прикол в том, что в реальности ни кто не пишет сервис с новым апи с нуля. Просто добавляют в старый. Если ты на каждую итерацию добавляешь по сервису, то будет зоопарк.

Насчет жуткой развилки в коде --- эээ, хттп роутер сделает всё за тебя

4. Чтобы горизонтально промасштабироваться, снять загрузку с одного сервиса, можно просто вместо одного сервиса повесить 10 одинаковых сервисов. Каждый из них будет харчеваться на сервис бас и выгребать по мере загрузки сообщения. На рест сервисе без костылей, это не сделать никак. Это тупое дерганье методов одного эндпоинта, одного сервиса.

Лоад балансеры придумали давно.

5. Чтобы сделать отказоустойчивый сервис, например если Сервис А, отваливается вступает в работу Сервис Б, вешаются два сервиса на сервис бас с разными приоритетами обработки сообщений. На Рест это не решается никак.

Лоад балансеры придумали давно. [x2]

6. Чтобы сделать асинхронный вызов, вы запустили джобу и ждете нотификейшин. На сервис бас это делается бай дезайн, на рест это делается через костыль колл бека или тормозной луп или никак.

Вот только нотификейшн — это тоже костыль, потому что туда нужно добавить cookie, чтобы хоть как-то соотнести результат запрос с ответом. В итоге мы получаем мапы куков на запросы на каждый тип запроса на клиенте, еще и плохо аудируемые. На ресте их можно хотя бы в роутере просмотреть.

7. Если сервис уходит в локдаун, сообщения могут скапливаться, перемещатся в дедлеттер и возвращаться обратно на сервис бас, для того чтобы возобновить прохождение распредлеенного процесса между 100500 сервисами. В Рест если запрос отвалился то все, давай досвидания.

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

Забыл записать 8м пунктом. Конечно на топологии сетей вроде Сервис Бас возможна ситуация когда один сервис бродкастит сразу нескольким потребителям сообщения. На Рест такое естественно невозможно.

Пуши — это по факту единственное, где оно реально нужно. В остальных случаях — тормоза и оверинжинееринг

Single point of failure, не масштабируемость, огромные затраты на траффик.

Мне лень даже обьяснять, но просто прийми за факт, везде .. _везде_ в серьезных системах архитектурный шаблон это отправка сообщений, а не дерганье эндпоинтов. Эта штука происходит начиная от твоей головы, где нейроны посылают импульсы в сети на 90 миллиардов потенциальных получателей, до сети интернет где бегают пакеты между сетями, материнской платой где тотже бас утилизирует трафик между, видеокартой, винчествером и процессором и даже в сраной виндоуз весь юай построен на отправке сообщений в оконные функции. По другому это сделать просто невозможно, где есть требования как раз к масштабируемости трафику и вообще построения «живой» отказоустойчивой системы.

Дальше я не читал, поскольку не понимая базовые принципы, ты намолол чушь и предложил миллион всяких костылей вроде роутеров, балансеров и куки к своим Рест поделкам.

до сети интернет где бегают пакеты между сетями

В сетях вообще-то есть разница между unicast, multicast и broadcast

материнской платой где тотже бас утилизирует трафик между, видеокартой, винчествером и процессором

Между процом и видяхой вообще-то юзается AGP — accelerated graphics port, а ни как не бас.

даже в сраной виндоуз весь юай построен на отправке сообщений в оконные функции.

WinAPI не является примером хорошего АПИ, ага

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

Тут на самом деле надо воспомнить, что весь такой на сообщениях GNU Hurd почему-то не взлетел, а ляликс — взлетел.

Дальше я не читал, поскольку не понимая базовые принципы, ты намолол чушь и предложил миллион всяких костылей вроде роутеров, балансеров и куки к своим Рест поделкам.

Не, ну если ты не шаришь за рест, так сразу и скажи. Сложно дискутировать с человеком, который разбирается в технологиях только по комиксам.

В сетях вообще-то есть разница между unicast, multicast и broadcast

Интернет построен по принципам полиморфной сети. Тоесть сети, которая постоянно меняется. Поэтому и архитектурный шаблон здесь тотже сервис бас, на который просто скидуются сообщения, а дальше их разгребают. Рест же синоним сети, где один узел прибит гвоздями к другому узлу. И балансеры не меняют здесь координально картину.

Между процом и видяхой вообще-то юзается AGP — accelerated graphics port, а ни как не бас.

Ты готов ответить за все материнские платы ? За внутренность процессора и даже самой видеокарты ? По-моему ты пропустил. Это _единственный_ архитектурный шаблон который позволяет хоть както сносно мапить тысячи отправителей и тысячи получателей в системе в которой еще и все меняется.

WinAPI не является примером хорошего АПИ

Является. Потому что оно работает на самой популярной ОСи и переписывать эту часть никто не будет.

Не, ну если ты не шаришь за рест, так сразу и скажи

В Ресте нечего шарить. Это тупое дерганье методов, с которым я имею дело последние лет 15. Вот в Сервис Бас да, не каждый галерный архитектор вообще понимает этот архитектурный шаблон. Не понимает как вообще в живых системах все устроено.

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

Лолнет. Запусти два компа в одну сеть с одним айпишником.

Ты готов ответить за все материнские платы ? За внутренность процессора и даже самой видеокарты ? По-моему ты пропустил. Это _единственный_ архитектурный шаблон который позволяет хоть както сносно мапить тысячи отправителей и тысячи получателей в системе в которой еще и все меняется.

Оценочное суждение, неподкрепленное аргументами

Является. Потому что оно работает на самой популярной ОСи и переписывать эту часть никто не будет.

Ахахахахахаха!!!!! Его не будут переписывать потому что обратная совместимость. А хотелось бы многим.

В Ресте нечего шарить. Это тупое дерганье методов, с которым я имею дело последние лет 15. Вот в Сервис Бас да, не каждый галерный архитектор вообще понимает этот архитектурный шаблон. Не понимает как вообще в живых системах все устроено.

Ну я пока контраргументов не увидел

Лолнет. Запусти два компа в одну сеть с одним айпишником.

Открой для себя DNS наконец.

Ахахахахахаха!!!!! Его не будут переписывать потому что обратная совместимость. А хотелось бы многим.

Что конкретно ты собрался там переписывать. Обработку сообщений оконными функциями ? "Может вы и способ знаете ?"©Преображенский

Справа шпагетти, слева трушный рест.
Тут главное не перепутать !
ibb.co/bdLJK7J

То с чем вы боретесь, называется имплементация REST стиля с применением HTTP как транспорта, URI как идентификатора ресурсов и Json как формата данных.
Как по вашему, если заменить HTTP на Websockets, URI на UUID и оставить Json — это все еще будет REST? Если нет, то какой принцип REST будет нарушен?

То с чем вы боретесь, называется имплементация REST стиля с применением HTTP как транспорта, URI как идентификатора ресурсов и Json как формата данных.

Еще раз. Базовые принципы Сервис Бас.
Вы не знаете _кто_ обработает сообщение, _где_ обработает это сообщение и _когда_ пришлет вам ответ.
Это позволяет строить полиморфную «живую» коммуникационную сеть, когда потребители не привязаны жестко к поставщикам услуг. Плюсы такой сети я описал выше в виде 8 пунктов + 1 еще (бродкаст сообщений) добавили по ходу дела.
Ниодин из этих пунктов простым способом не реализуется через РЕСТ. Можете его заворачивать в любую конфетную обертку, дело это не меняет.

Не ответили на вопрос, ну да ладно) Я веду к тому, то что вы описываете — и есть REST. Если вы потрудитесь ознакомиться c ограничениями, которые лежат в основе REST, то нигде в 6 из них не найдете требования клиенту знать о том, кто и как запрос обработал и тем более о синхронности ответа. Спорить тут стоит о применении конкретных протоколов и дизайнов систем. А сервис бас всего лишь один из видов event-driven архитектур и тут есть, как и везде, свои трейд-офы, как усложнённое теститование, трэйсинг, проблемы с очерёдностью сообщений... youtu.be/M6CDaZ1cxIs?t=203

Я веду к тому, то что вы описываете — и есть REST

Что за бред вы несете.
Как с помощью Рест устроить например бродкаст (пуш) сообщений (один отправитель кастит сразу на 10000 получателей сообщения).
Как устроить асинхронность получения сообщения.
Как сделать профилирования ВСЕХ сообщений которые отправляются всеми сервисами. Тоесть например я хочу узнать какой из 100500 сервисов отправляет в сообщение слово Vasya
Как устроить параллельное разгребание сообщений сразу 100 одинаковыми сервисами (горизонтальное масштабирование). И тд.

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

Бред не бред, а о постоянном соединении между клиентом и сервером я уже намекал) Если для вас REST = Json через HTTP 1.1, то это ваши личные проблемы. Копировальные машины тоже «ксероксом» называете? Продолжайте)

сервером я уже намекал

Вы намекаете на резиновую лодку когда говорят о пароходах. И вам уже в который раз выписывают список вполне осязаемых приимуществ суден по типу пароход, перед резиновой лодкой.
А вы пролоджаете утверждать, если сделать на резиновой лодке трубочку диаметром HTTP 1.1 и пердеть в нее как пароход, то получится почти пароход. Не получится. Уверяю. Продолжайте намекать.

Открою тайну: вебcoket использует http для установления соединения, а дальше это TCP)

Открою тайну: нет никакого ООП. Есть только перемещение чисел в регистрах процессора, комманды mov, jmp и тд. В чем посыл сообщения ?

Поясните тогда вашу мысль о

трубочку диаметром HTTP 1.1

когда я говорю о соединении клиента с сервером через tcp/ip (или вебсокет) которое и дает возможность делать асинхронные ответы и бродкаст...

Рест сервис не подразумевает асинхронных оповещений.
Есть только костыли вроде колбеков или лонг полинг. Бродкаст в туже калитку.
Сам tcp\ip и вообще построение интернета, действительно ближе к Сервис Бас, о этом я еще раньше писал. Но смысл Реста в том, чтобы координально ограничить те свойства которые он получил от tcp\ip, чтобы рядовому хомячку получить няшный юайчик по дерганью ремоут методов, собственно к тому, к чему он привык в своих хелоу ворд поделках.

Рест сервис не подразумевает асинхронных оповещений.

Вот откуда вы это взяли?) TPC-based сервис может быть тоже RESTful, как и HTTP-based со своими преимуществами и недостатками. Думаю моя мысль уже яснее быть не может. Спасибо за диалог.

TPC-based

Первый раз слышу это слово.
Решили придумать новые термины ?

TCP.
Я к вашим

координально

относился снисходительно)

Рест сервис не подразумевает асинхронных оповещений.

как будто http умеет в асинхронность. я запутался.

http не умеет. Сервис Бас умеет, tcp/ip умеет

tcp/ip умеет

tcp/ip тоже не умеет асинхронность на столько что его даже удалили из http/3 ака quic

*Взяв попкорн*
ану-ану

Хто в треді розкаже людям про server-initiated messages і чим вони відрізняються від асинхронності

есть, как и везде, свои трейд-офы, как усложнённое теститование, трэйсинг, проблемы с очерёдностью сообщений... youtu.be/M6CDaZ1cxIs?t=203

Это потому что Сервис Бас по своим концепциям на две головы выше чем Рест, но по реализации еще хуже чем Рест. На самом деле, нужно решать проблему не дерганья методов (Рест), не обмена собщениями (Сервис Бас), а именно синхронизации систем. Тогда можно хендлить ситуации типа закорапшеных данных, отправки и получения данных балками и тд. Но эта другая обширная тема эволюции транспортных протоколов. Для начала нужно понять, почему Сервис Бас это не Рест, а намного лучше, а потом уже переходить к новой теме, к следующей ступеньке эволюции и разбираться как можно улучшить Сервис Бас.

Как всегда в тред прибежал Пение и несет техночушь. Обычная среда.

POST /findRecipient

{
«companyId»: «1323»,
«serviceId»: «1234A»
}

Це буває цілком виправдано, особливо коли у нас розвинена система фільтрів. Довжина URL має свої обмеження, і що найгірше, ці обмеження не стандартизовані. У різних браузерах\веб-серверах вона може бути різною (у різноманітних проксі на шляху запиту в тому числі).

Набагато краще такі фільтри передавати body запиту, а не через query

С одной оговоркой, что я бы использовал тут метод коллекции, а не точку входа, из соображений разделения сущностей:

POST /Recipients/Find

Повторю ещё раз: Единственная причина использования REST — это мода на его использование. Никаких преимуществ он не даёт. Как есть мода на вероисповедание, так есть мода на REST, и она тоже пройдёт.

Если только вам не нужно продавать продукт в виде API, вам эта хрень полезна ничем. Делайте свои протоколы на основе стандартных, используйте чужие протоколы, КАКИЕ ХОТИТЕ, используйте жизненный цикл данных КАКОЙ ХОТИТЕ, и вообще можете не ставить во главу угла сущность «ресурс» — ваша бизнес-модель может совершенно иначе трактовать информационные потоки и иметь совершенно иную модель ВЛАДЕНИЯ информационными объектами.

Два проекта в которых я работала открывали свое API наружу, для того чтобы с нами могли интегрироваться партнеры и другие пользователи интернета. Так вот, гораздо меньше WTF возгласов вы услышите от своих пользователей (пользователей вашего API) если оно REST а не мы-сами-придумали-свой-формат-общения. И вы гораздо меньше времени потратите на обьяснение как с вашим апи коммуницировать.

Причем в одном из проектов изначально не задумывалось делать API публичным (единственным пользователем был наш же фронтенд) а потом решили открыть, так как получили заманчивое предложение запартнериться, от которого неразумно было отказаться. Поэтому даже если ваш фронт это единственный пользователь, не факт что так будет всегда.

Хотите сказать, внутри этой REST-обёртки не лежит то самое WTF? Ну-ну. Я ж так и сказал, если продукт на продажу, то конечно он должен быть понтовым. А если для дела — то вам шашечки или ехать?

Типичное применение REST — выдача какого-то ресурса. Но оно всегда так работало, даже до того как стало называться RESTом. Но для сложной логики REST API — всегда натягивание глобуса на сову.

да не будет никакого «И вы гораздо меньше времени потратите на обьяснение как с вашим апи коммуницировать». Просто компанию с таким костылAPI тихо, или нет, пошлют и пойдут к тем, с кем легко и просто интегрироваться за адекватное время, а не изучать, почему их АПИ на запрос создания заказа прислало ответ «запрос мне нужно присылать в формате application/мойМилыйКотенок3.1, только после 12:37 РМ и только по SMTP».
Ну и судьба авторов таких АПИ понятна, и даже масса текста капсом не поможет.

В тех апи которые не РЕСТ — там в 99% вообще чорт ногу сломит. В РЕСТе хотя бы более-менее все просто и хоть немного стандартизировано, и обычные кодерки могут и сами навоять и разобрать что другие сделали. А когда начинают запускать всех подряд в остальные колхозы, то без слез на это смотреть невозможно.

Как будто там где REST под этой обёрткой не то же самое говно. И не чёрт ногу сломит. И не надо перекомпилировать обёртку на стороне клиента, как только добавился какой-то параметр — ибо бэкенд как и раньше пишут говнокодеры, по которым ДияСити плачет.

И вправду. Лучше вместо популярного и всем понятного REST написать какой-то треш, в котором никто не разбирается.

Лучше вместо известного стека под капотом юзать самописные велосипеды. Не потому, что они дают «преимущество», а потому, что «мы ведь умные и лучше знаем».

А потом дело за малым — называем это «корпоративная бизнес-логика, энтерпрайз» и делаем вид, что что-то понимаем в тонких материях.

Жаль только, что все клиенты уйдут к конкурентам, которые пишут людские АПИ и что найти новых сотрудников, которые согласятся работать с «кодом победителей олимпиад», будет ой как не просто.

Всем понятного? Да это тот же велосипед, только ты его в рест завернул. Рест хорош для того, для чего он предназначался — выдача READ-ONLY ресурсов. Для всего остального это просто тупорылая упаковка, и ничего кроме реализации отдельного слоя преобразований (притом с обеих сторон) она не даст.

А ну, давай расскажи, как на том же РЕСТе сделать транзакционную целостность при сохранении. А никак. Нет такого, не предусмотрено, потому что рест не для этого придуман. А значит — через жопу с костылями мы куда глаза глядят...

Не могу понять при чем тут транзакционная целостность? РЕСТ это набор соглашений по части нейминга и структурирования ендпоинтов АПИ. Это правила построения внешнего интерфейса для взаимодействия с системой

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

Но даже если так получилось, что система под капотом — кривая. Написать рест апи, которая может в транзакционную целостность — совсем не проблема.

РЕСТ это набор соглашений по части нейминга и структурирования ендпоинтов АПИ.

Ходят слухи, что даже в дисере упоротого филдинга этого нет. А фокусы типа /customers/1/orders/2 , чисто эротические фантазии хомячков, считай народное творчество.

У меня один вопрос. Зачем писать Рест апи если можно его не писать. Вот взять эту страницу на Доу. Давайте покроем ее Рест апи. На вскидку нужны методы: Добавить комментарий, Редактировать комментарий, Удалить комментарий. Редактировать текст темы, Редактировать текст заголовка и тд.

А теперь представим что система построена по другому. Есть Локальная копия страницы. Есть Серверная копия страницы в базе данных. Ты СИНХРНИЗИРУЕШЬ свою локальную копию с серверной. Редактируешь как хочешь и что хочешь свою локальную копию и потом синкаешь ее с сервером.

Итого плюсы:
1. Мы читаем всю страницу целиком
2. Мы ее редактируем, можно балком, не дергаем рест на каждое мелкое изменение
3. Мы можем работать в офлайне со своей страницей
4. К нашей офлайновой странице могут прилетать обновления с сервера без перезагрузки, экономия трафика
5. Мы можем мержить нашу страницу по правилам, целостности, версионности и транзакционности с серверной страницей

Вопрос. Зачем Рест ? Чтобы просто дергать серверные методы ? Чтобы написать килотонну однообразного кода ? И зачем по пустякам зае*бывать сервер, да еще через три прослойки маперов и дто ?

то, что ты описал можно заимплементить используя REST соглашения. Вопрос: зачем выдумывать велосипеды?

ты сам определяешь насколько будет гранулярная твоя апишка. Сущностью может быть как вся страница целиком, так и каждое отдельное слово со страницы. Это определяет не РЕСТ, а проектировщик апи.

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

то, что ты описал можно заимплементить используя REST соглашения. Вопрос: зачем выдумывать велосипеды?

Нельзя заимплементировать. Рест тут как пятое колесо. Рест не умеет в асинхронность (кроме жутких костылей). Рест не сможет отправить скопом большой блок данных (есть ограничения). Рест не сможешь отправить большую картинку или видео в блоке данных. Рест не сможешь его разбить на блоки. Рест не умеет в транзакционность.

Зачем Рест когда он не нужен ? Когда от него все тормозит ? Когда он только все ломает и заставляет писать килотонны примитивного однообразного кода, прячущего крупицы полезной бизнесс логики ??

Никто не спорит, что бывают специфические задачи, для которых нужны специфические решения.

Обновление комментариев на сайте типа доу это специфическая задача ? А можно пример не специфической ?

боюсь, на этом я выхожу из чата

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

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

Мог бы просто скидывать линку на статью и не было бы больше вопросов. Комьюнити будет тебе благодарно за вклад!

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

Рест не умеет в асинхронность (кроме жутких костылей). Рест не сможет отправить скопом большой блок данных (есть ограничения). Рест не сможешь отправить большую картинку или видео в блоке данных. Рест не сможешь его разбить на блоки. Рест не умеет в транзакционность.

Зачем Рест когда он не нужен ? Когда от него все тормозит ? Когда он только все ломает и заставляет писать килотонны примитивного однообразного кода, прячущего крупицы полезной бизнесс логики ??

Чувак, что ты куришь? Рест — это не протокол, блеать. Он в принципе не может

отправить большую картинку или видео в блоке данных.

. Он в принципе ничего не знает о транзакционности.

Рест — это просто набор рекомендаций для имплементации взаимодействия систем по протоколу http. У которого, естветственно, как и любого другого протокола, есть свои ограничения и своя зона применения.

по протоколу http

То есть уже только по http?

Слушайте, для меня как даже не архитектора, а идеолога, все эти сорта технологий старый добрый Remote Procedure Call. Ты можешь завернуть его в любую обёртку, RPC, Sockets, DCOM, REST, WCF и так далее, суть не поменяется. Суть дёрнуть метод ремоут хоста, маршаля параметры в одну сторону и получая синхронно результат в другую. Все эти технологии являются промежуточным звеном на пути более правильных имплементации транспортных концепций.
И даже на основе сервис Бас можно видеть что по функциональности любой RPC — просто кривая лопата по сравнению с экскаватором.

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

Мне даже удивительно сколько моих усилий положено чтобы вытянуть людей на уровень понимания выше,

Мне гораздо более удивительно что нет элементарного понимания двух базовых общеинженерных принципов:
a) Серебряных пуль не существует
б) Для оптимального решения задач разных типов требуются разные инструменты — использовать трехкубовый экскаватор (сервис бас) чтобы выкопать ямку под саженец ( простой stateless API ) - наверное можно, но зачем?

Кстати, а можно уточнить что такое

И даже на основе сервис Бас

«сервис Бас» — это что именно в данном контексте ? ESB как компонент SOA ? Обобщенное название message brokers ? Какая-то конкретная имплементация ?

a) Серебряных пуль не существует
б) Для оптимального решения задач разных типов требуются разные инструменты — использовать трехкубовый экскаватор (сервис бас) чтобы выкопать ямку под саженец ( простой stateless API ) - наверное можно, но зачем?

Омг. Как скучно. Как только начинаешь писать более глубокие вещи, сразу срабатывает универсальная отмазка на собеседовании:
1. Универсальных серебрянных пуль не существует.
2. Каждой задачи свой инструмент

Самое интересное, что этой отмазкой можно оправдать абсолютно любую треш технологию.
— Здраствуйте, ваша сломанная зубочистка не годится как зубная счетка
— Серебрянных пуль не существует ! Для разного решения задач разные инструменты ! Зато этой сломанной зубочисткой удобно ковырятся в носу, а иногда и в ухе.
— Хм, ну да ну да.

Все таки можно уточнить такие

более глубокие вещи,

как

«сервис Бас» — это что именно в данном контексте ? ESB как компонент SOA ? Обобщенное название message brokers ? Какая-то конкретная имплементация ?

Зачем привязываться к названиям ? Сервис Бас в данном контексте это транспортный уровень, который реализован как асинхронная отправка сообщений получателю через общую шину данных. Примеры такой реализации есть как на аппаратном уровне, так и в коде в виде тех же оконных функций в вин32 и заканчивая разными ESB и так далее.

Вот здесь я нарисовал топологию. Чтобы было понятно фундаментальное отличие между синхронным колом между двумя точками и асинхронной отправкой сообщения через общую шину данных
ibb.co/bdLJK7J

Сервис Бас в данном контексте это транспортный уровень

Я все равно не понял. Транспортный уровень — имеется в виду 4 уровень OSI модели? «сервис бас» — это новый протокол, убийца TCP ?

Хорошо, тогда я задам такой вопрос.
Синхронный и Асинхронный кол тебе о чем-то говорит, как архитектурный шаблон ?
Или ты тоже бы предпочел его привязывать к какому-то уровню OSI или Rest, Esb, Soap, WCF, Json, DCOM и тд.
Ты на уровне самих архитектурных концепций можешь мыслить ?
Что есть основа, что есть последствие ?
Например есть понимание, что тотже синхронный вызов является всеголишь подмножеством асинхронного вызова, но с разницей что ты после отправки сообщения в лупе ждешь ответ ?

Ты на уровне самих архитектурных концепций можешь мыслить ?

Когда

OSI или Rest, Esb, Soap, WCF, Json, DCOM

смешиваются в одну кучу, то нет — такой уровень абстракции находится за пределами моих скромных телепатических способностей :))

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

А в Майнкрафте говорят построили модель процессора Пентиума из кубиков. Что было первым. Майнкрафт или процессор Пентиум. Вот вопрос.

старый добрый Remote Procedure Call

Так а чем оно плохо? Оно охренительно работает. Проблема в дурочках-пророках, которые навязывают использовать все методы, коды и именовать урлы как написано в цитатно-догматическом документе.

Оно охренительно работает

Оно охренительно работает если у тебя точка А и точка Б в одном и томже адрессном пространстве, одном ОЗУ.
Тогда коммуникация между двумя этими точками через процедур колл.
1. Без сбоев
2. Без задержек
3. Без секурити
4. Без масштабирования
5. Без проблем корапшина данных
6. Без проблем передачи блока данных любого размера
7. Без проблем асинхронной передачи данных
и многое другое.

Если между точкой А и точкой Б появляется еще одно звено — транспорт, которое имеет такие свойства как латенси, офлайн режим, ширина канала и тд, тут то и выясняется что нельзя маня мир с локального адрессного пространства удачно перенести на мир распределенных машин.

Ты СИНХРНИЗИРУЕШЬ свою локальную копию с серверной

Як
0) що саме буде передаватись на сервер і назад
1) валідувати
2) санітайзити
3) розрулювати конфлікти

Это тебя как разработчика не должно интересовать. Как не интерсует какие куда ходят пакеты или передаются сигналы в твоей сетевой карте. Ты работаешь со своей локальной копией доменной модели. Локальная копия умеет синкаться с серверной копией. Всё.

WUT?

Якщо б ми вели розмову про драйвера мережевих карт, то якраз цікавили б

Як

Локальная копия умеет синкаться с серверной копией

?
Хто написав код? Де він? Як там вирішені проблеми, що я навів вище?

Як там вирішені проблеми, що я навів вище?

Выришени как в гите или гугл драйв или дропбокс. Тыщи их систем которые просто молча синкают данные без лишней пыли.

Як в гіті проходить перевірка прав на запис блока кода і

1) валідувати
2) санітайзити
3) [auto] розрулювати конфлікти

?

Тыщи их систем которые просто молча синкают данные без лишней пыли

Які саме системи можуть таке робити в середовищі де не можна довіряти користувачу?

Як в гіті проходить перевірка прав на запис блока кода і

В гите есть система прав для юзера. Если ты не имеешь прав, код ты свой не замержишь. Гит умеет валидировать можно ли накатить патч. Гит умеет разруливать конфликты и удалять давнюю историю (если нужно). Гит здесь просто в качестве удачного примера, который быстро вычисляет что нужно дослать, досылает и выравнивает твою локальную версию согласно версии на сервере. И наоборот.

Переінакшу питання, бо ви мабуть не зрозуміли його

Як дати юзеру права на додавання/редагування/видалення коду тільки в один файл тільки в один блок в гіт?

Ну і про іншу частину питання не забудьте

Разве мы собрались переписать гит ? Я же говорю, он просто как пример концепции. Есть две базы данных, они синкаются между собой. В данном случае нет никаких проблем проверить, что у тебя есть права накатить этот патч. Если нужно, по каждому изменяемому атрибуту проверить наличие прав. Если прав нет, значит ролбек патча до тех пор, пока патч не пришлет клиент такой, который можно полностью накатить.

гіт це не бд для систем з багатьма користувачами
гіт не має системи прав
гіт не вміє валідувати
гіт не вміє санітайзити

Git is a «stupid content tracker.»

Нащо ви вибрали гіт як приклад, якщо з нього потрібен тільки функціонал diff?

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

с валидацией патчей и секурити
Як дати юзеру права на додавання/редагування/видалення коду тільки в один файл тільки в один блок в гіт?
гит работает в многопользовательском режиме

lmao

Я все думав, що ви можете самі зрозуміти, що несете дичину
Але я помилявся

В гите можно дать право на чтение определенной бранчи и запись определенной бранчи. Все бранчи формируют дерево. Если это не многопользовательское гранулярное секурити, то что это ?

Или даже не так. Ок, у тебя есть какое-то свое странное требование к системе секурити. Вопрос, почему ее нельзя заимплементить, принципы распределенного хранилища этому как-то фундаментально мешают ?

Git itself does not have such feature, but many hosting providers do

Тобто у вас немає базового розуміння гіту. Це вже цікаво

странное требование к системе секурити

Чому authentication дивна вимога?

До чого розподіленість?

Як

1) валідувати
2) санітайзити
3) [auto] розрулювати конфлікти

?

Ну и зачем постить цитаты с стековефлоу 5 летней давности ?

Вот, читай. Выдают права на бранчи и даже есть юзеры группы и роли.
Не знаю чего тебе ещё не хватает для секурити.

docs.microsoft.com/...​issions?view=azure-devops

Azure Repos | Azure DevOps Server 2020 | Azure DevOps Server 2019 | TFS 2018-TFS 2015

Це вже смішно
Але продовжуйте

Там ще 5 інших питань є

А что смешного ? Девопсы настраивают секурити для гит бранчей. Что не так ? Чего не хватает ?
Остальные пытання ещё более глупые чем с секурити. Ты просто противоречишь сам себе. Например говоришь что нет валидации в гите и при этом спрашиваешь как резолвить конфликты. Но блеать если у тебя нет валидации на запись откуда же конфликты ?
Гит и валидирует возможность патча и помогает резолвить конфликты

Смішно, що ви не розумієте про що кажете, і почали вигадувати на ходу

Нажаль, в ході бесіди ви не показали, що зрозуміли мої натяки

. Ты СИНХРНИЗИРУЕШЬ свою локальную копию с серверной.

Используя какие протоколы ?

К нашей офлайновой странице могут прилетать обновления с сервера без перезагрузки, экономия трафика

Используя какие протоколы ?

Ну а в целом, учитывая что параллельно с тобой над страницей работат еще X человек — ты, по факту, заново изобрел git merge между своим бранчем (локальной копией) и мастером (сервером)

Ну а в целом, учитывая что параллельно с тобой над страницей работат еще X человек — ты, по факту, заново изобрел git merge между своим бранчем (локальной копией) и мастером (сервером)

В Гите действительно организованы эти принципы. И гит ровно также вынес всякие сорц контрол, свн и других просто в одну калитку. Не смотря на то, что первые лет пять этот гит толком никто не понимал, он невероятно глючил, а его код и продолжает быть жутчайшим откостылированным говнокодом.

В таком случае ты как бы должен знать, что git merge — это очень проблемная операция в случае конфликтов, в общем случае не имеющая автоматического решения (ну, за исключением радикального подхода типа —ours )

Естественно, в случае конфликтов есть правила резолва этих конфликтов.

Рест не решает проблем. Там нужно много педалить кода и много ограничений.
Чаще всего в системах стоит задача не дернуть метод другого сервиса а синхронизировать данные между сервисами, между фронтом и сервисом. И идеальный и супер понятный апи, работать с удаленной базой как с своей родной локальной.

Если мне на каждое энтити нужно педалить по три метода, а потом должна ещё болеть голова о масштабируемости, синхронизации, целостности, кешировании, версионности, гибкости контракта, то это тупик.

И именно так выглядят многие системы которые заигрались в рест

Боюсь, что проблема не в ресте, а в программистах 😅

Про ассемблер тоже когда то так говорили. Повыдумывали тут высокоуровневые абстракции. Дайте хомячкам дергать методы в глобальном неймспейсе ! Дайте спокойно напедалить тонны однообразных прослоек кода, которые все что делают, прячут крупицы полезной бизнесс логики.

Если только вам не нужно продавать продукт в виде API, вам эта хрень полезна ничем. Делайте свои протоколы на основе стандартных, используйте чужие протоколы, КАКИЕ ХОТИТЕ, используйте жизненный цикл данных КАКОЙ ХОТИТЕ

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

REST оказался хорошим способом именно для программистов формализовать мышление в методах взаимодействия

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

В багатьох прикладах в GET запитах вказано Content-Type: application/json. Думаю варто замінити на Accept: application/json

Ще непогано мати спеціальний інтерфейс відповіді сервера. Пишу на TypeScript, але думаю читабельно буде й для інших:

export interface AnyObj {
  [key: string]: any;
}

export interface ApiResponse<T, M = AnyObj, E = { message: string }> {
  data?: T[]; // Дані
  meta?: M; // Метадані
  error?: E;
}

lang=UA — це також не стандартно. Стандартно це lang=uk.

хороший доклад, но у web api все-таки своя специфика

Версионность. Версионировать API можно в URI или в заголовках. Выбирайте любой способ, главное создавайте версионность. Она позволяет вносить изменение в систему самым безболезненным для потребителя путем.

Не согласен. Версионность — это уже последняя мера, когда другого выхода нет. При дизайне публичного API нужно отталкиваться от принципа наименьшего изменения (иногда достаточно просто задепрекейтить конкретные ресурсы и свойства), а если вы делаете «внутреннее» API для какого-то мобильного/веб-приложения, то версионность может быть вообще избыточна.

А как поддерживать обратную совместимость без версионности?

А всем API нужна обратная совместимость?
А все API, которым таки нужна обратная совместимость, меняются настолько чтоб оправдать сразу написание и поддержку второго «контракта»?

Есть много книжек и статей, в том числе небезызвестный сайт Мартина Фаулера, которые описывают принципы дизайна компьютерных систем, чтоб предотвратить возникновение такой проблемы. В кристаллизированном виде это идея, что API должно быть консервативно в том, что оно возвращает и либерально, в том что оно принимает.

На примере: была когда-то такая популярная система инвентаризации TradeGecko (сейчас это QuickBooks Commerce). В какой-то момент они решили что поле поставщик на SKU должно быть не строкой, а массивом. По логике этой статьи, хорошим тоном здесь была бы новая версия API. Но там все решили гораздо проще: сохранили старое свойство supplier в JSON и добавили новое suppliers — и старые, и новые клиенты довольны.

Подобных ситуаций среди коммерческих API масса, но большинство почему-то смотрит, как API которым уже по 5-10 лет ожидаемо решают написать вторую версию и считают что это какая-то данность. Я ж не говорю, что версионность плохая, а что надо подумать, прежде чем добавлять какую-то потенциально избыточную конструкцию в свою систему.

Если API для внутреннего использования, то конечно можно обойтись окрестрацией деплоев и релизов, чтобы все изменения апишки согласововались с его потребителями.
Но не будет ли это в итоге еще хуже, чем поддерживать разные версии апишки?
Ясно, что если изменения апишки не меняют публичный контракт, то новая версия не нужна — это и ежу понятно.
А если API публичное, то

А как поддерживать обратную совместимость без версионности?

А кто сказал, что у API вообще можно вменяемо делать обратную совместимость? Жизненный цикл API, где клиент неподконтролен — только разбухание и поддержка атавизмов.

Правильный вопрос — это насколько есть понимание, что ЦЕНА линейного роста API во времени — весьма невысокая. Гораздо дешевле обходится поддержка многих версий API, чем убеждать переделывать уже написанные программы, которые работают через «устаревшую» версию. Даже если вам придётся поддерживать 100 версий — просто сделайте это, благо поддержка в основном сводится к прописыванию дефолтов в бекенде и регулярном обновлении тестов. И пусть конфиги вместо 1 килобайта весят 200кб, никто не заплачет.

так это и имеется в виду под обратной совместимостью.
Была АПИ в1, мы захотели сделать изменения, меняющие публичный контракт. Как это сделать не создавая АПИ в2, чтобы клиентам на в1 не пришлось менять свой код?

версионирование это один из методов обеспечения обратной совместимости 😅

«внутреннее» API для какого-то мобильного

Для АПИ мобильных приложений которые будут эволюционировать версионность необходима — некоторые клиенты могут не обновляться годами продолжая пользоваться продуктом.

Поэтому продумываем заранее функционал приложения и кидаем старым клиентам ошибку с просьбой/кнопкой обновления приложения) Банковские приложения позволяют себе такое

о да, потом смотрим как увеличивается churn во время таких обновлений, прикидываем сколько компания потеряла и начинаем версионировать. force update функционал используется в крайних случаях и в приложениях с очень лояльной клиентской базой с сильной привязкой к продукту

Ошибки. Иногда HTTP-статусов не хватает, чтобы описать ошибку. Или нужно уточнить, в чём именно проблема. Для этого вся информация об ошибке передается в теле ответа. Сейчас нет конвенций «Как правильно отображать ошибку». Какой бы формат вы не выбрали, придерживайтесь его.

Само по себе описывать ошибки бизнеса http кодами уже огромная ошибка. У меня на проекте один хттп вызов может запустить огромную бизнес транзакцию, что вернет на клиент помимо данных, большой иерархический объект со своими кастомными статусами выполнения/завершения/успешности по каждой операции/подоперации.

Одно другому не мешает весьма не мало случаев когда, апи еще и список ошибок вываливает. Если ошибки не критические то можно вернуть 2**, а если подобное действие не проходит и ошибки критического характера то в зависимости от текущей ситуации можно вернуть либо 4** либо 5**. Это адекватно, а вот возвращать на все 200 считаю порочной практикой.

http200 — 404 ресурс не знайдено
чи ще краще
http500 — головна сторінка

А если при попытке заказа билета на автобус с невалидным ковидным сертификатом в хидерах/боди возвращай 451 datatracker.ietf.org/doc/html/rfc7725. Это ведь так очевидно. Апи консьюмеры сразу посмотрят на 451 в респонзе и к ним придет рой филдинг с нимбом и немедля поместит в их головы тайное знание, что эта х**та означает и как этим пользоваться.

Апи консьюмеры

Мають мати мінімальні знання про взаємодію в вебі чи банальне вміння гуглити
В тілі відповіді — помилка описується текстом

Есть надежда, что АПИ консьюмеры могут в английский достаточно чтобы понять:

datatracker.ietf.org/doc/html/rfc7725.
Responses using this status code SHOULD include an explanation, in
the response body, of the details of the legal demand: the party
making it, the applicable legislation or regulation, and what classes
of person and resource it applies to.

Мне больше интересно почему им 403 не подошло. Или если они в комитете не будут плодить коды, то их просто повыгоняют?
Acknowledgements

Thanks to Terence Eden, who observed that the existing status code
403 was not really suitable for this situation, and suggested the
creation of a new status code.

Thanks also to Ray Bradbury.

ЗЫ А если в бабу вошло наполшишечки разве на такой прекрасный случай не нужен новый код?

Ваши споры о том какой код вернуть в Рест поделке напоминают споры, куда ляпнуть в коде goto.
Какая собственно разница какой код вернуть ?
Там проблема не в коде, а что над этим кодом просто гора должна быть бизнесс логики ПОД КАПОТОМ, а не рассыпана простыней по Рест поделке в виде кривого велосипеда. Вот краткий список на вскидку:
1. Что если сервер короткое время не отвечает. Делаем ретрай ? Сколько попыток ?
2. Что если сервер вернул токен не валиден, рефрешить токен, открыть юай, опять делать колл с новым токеном ?
3. Что если сервер упал, и должен поднятся его дублер. Как мой код должен узнать кто теперь дублер ? Какой теперь новый адресс ? Через какие балансеры костыли ?
4. Куда мне делать лучше всего колл, как на счет определить геолокацию, к какому серверу мне проще всего обратится ?
5. Как мне получить асинхронно апдейты ?
6. Что делать если мой стейт рассаглосовался с стейтом на сервере. Теперь есть куча фантомных айдишников. Миша все х*ня, давай по новой ?
7. Что если дернули метод, а версия апишечки теперь другая. Что должно произойти ?

Ты понимаешь глубину глубин. А вы какието сраные коды обсуждаете, вернуть 403 или 404.
Что не вернешь, будет РЕСТ поделка, которая архитектурно построена так, как будто все на одном тазике крутится, в одном адрессном пространстве процесса.

Ваши споры о том какой код вернуть в Рест поделке напоминают споры, куда ляпнуть в коде goto.
Какая собственно разница какой код вернуть ?

Люди из-за этого на кухне дерутся.

1. Что если сервер короткое время не отвечает. Делаем ретрай ? Сколько попыток ?

Как научим полли так и будет, если вообще кто-то этим заморачивается и просто не показывает попап «Ахтунг! Случилась х*ня».

2. Что если сервер вернул токен не валиден, рефрешить токен, открыть юай, опять делать колл с новым токеном ?

Да

3. Что если сервер упал, и должен поднятся его дублер. Как мой код должен узнать кто теперь дублер ? Какой теперь новый адресс ? Через какие балансеры костыли ?

да

5. Как мне получить асинхронно апдейты ?

Прикрути сокеты

Что не вернешь, будет РЕСТ поделка, которая архитектурно построена так, как будто все на одном тазике крутится, в одном адрессном пространстве процесса.

никакого реста не существует. есть http.

Единственная причина, почему мы имеем в 90% говнокод и приложение которое едва ворочается и глючит, что мы пытаемся решить проблемы не на том уровне на котором они должни быть решены. Все проблемы которые я описал выше _низкоуровневые_. Весь код который выше этого уровня, о этом _вообще_ ничего не должен знать. И тем более не должен знать о каких-то там кодах возврата которых мильен. И тогда твой код будет чистым, выкристализированным. В нем будет лаконичный слой бизнесс логики, а не жуткий набор костылей для решения проблем с уровня пониже.

Единственная причина, почему мы имеем в 90% говнокод и приложение которое едва ворочается и глючит,

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

И оттуда и получается

жуткий набор костылей для решения проблем с уровня пониже.

, который видимо должен решить некий абстрактный «сервис бас» просто по мановению волшебной палочки

который видимо должен решить некий абстрактный «сервис бас» просто по мановению волшебной палочки

Сервис Бас решает вполне конкретные проблемы. Он отвязывает поставщиков от потребителей, делая возможным всех общаться со всеми и при этом всем этим хорошо управлять.

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

Сервис Бас решает вполне конкретные проблемы. Он отвязывает поставщиков от потребителей, делая возможным всех общаться со всеми и при этом всем этим хорошо управлять.

Не то чтобы прямо полностью неправда, но далеко и совсем не так радужно, плюс сервис бас привносит массу своих специфичных проблем, так что

третиклассник который зубрит определения интегралов без понимания

- тут именно ты, потому как отсутствие практического опыта видно за километр

Если до тебя не доходит этот базовый шаблон транспортного проектирования

Что такое «транспортное проектирование» ? Топология сети? Или транспортных развязок на окружной Киева? Еще раз — пока не наведешь порядок в голове, код будет соответствующий

Лол, у меня на текущем проекте уже 3 года как Azure Service Bus — backbone огромного проекта, сталкивался с подобными решениями ( и не с одним ) и задолго до этого. Так что меня вполне забавляет читать ахинею, которую ты тут пишешь :))

Azure Service Bus

Да сейчас с ним работают все и я в том числе. Проблема в понимании. Спроси тебя, назови 10-15 преимуществ (концептуальных) сервис Бас перед синхронными вызовами и ты будешь блеть, что-то типа с сегодняшнего твоего репертуара «я слышал на синхронном соап можно сделать сервис Бас». Можно, как только пофиксаешь перформанц и всякие дед леттер Кью, а пока всё-таки что-то почитать по архитектуре приложений.

6. Что делать если мой стейт рассаглосовался с стейтом на сервере. Теперь есть куча фантомных айдишников. Миша все х*ня, давай по новой ?

Ты на уровне TCP или надTCP хочешь синкать базу/бизнес объекты с клиентом? Как?

также как это делает гит. Слева есть версия. Справа есть версия. Вычли одну версию с другой, получили диф. Отправили зааплаили. Конфликты зарезолвили. Если данные закорапшены сделали хард ресет на последний валидный снапшот. Все ходит поверх tcp.

Особенно хорошо это будет смотреться для бинарных / зашированных данных. Фигли там, бинарный дифф, байты смержили — вуаля, готово. Какие еще там CRC, подписи — пох

Особенно хорошо это будет смотреться для бинарных / зашированных данных. Фигли там, бинарный дифф, байты смержили — вуаля, готово

Не вижу здесь неразрешимых проблем.
Асинхронное шифрование помогает передавать данные наплевав на мен ин зе мидл. Сами данные шифруются на уровне атомарных атрибутов, мержатся они перезаписыванием.

1. Что если сервер короткое время не отвечает. Делаем ретрай ? Сколько попыток ?

Это описывается в бизнес-требованиях, к протоколу отношения не имеет

2. Что если сервер вернул токен не валиден, рефрешить токен, открыть юай, опять делать колл с новым токеном ?

Это описывается в бизнес-требованиях, к протоколу отношения не имеет

3. Что если сервер упал, и должен поднятся его дублер. Как мой код должен узнать кто теперь дублер ? Какой теперь новый адресс ? Через какие балансеры костыли ?

Это клиента не должно касаться и при нормальной реализации прозрачно для него. В самом же примитивном случае — follow 302

4. Куда мне делать лучше всего колл, как на счет определить геолокацию, к какому серверу мне проще всего обратится ?

Это клиента вообще не должно касаться. Это задача разного вида front-door сервисов на стороне провайдера

5. Как мне получить асинхронно апдейты ?

websockets в частности

6. Что делать если мой стейт рассаглосовался с стейтом на сервере. Теперь есть куча фантомных айдишников. Миша все х*ня, давай по новой ?

http — это, блеать, stateless протокол — исправить свою багнутую логику

7. Что если дернули метод, а версия апишечки теперь другая. Что должно произойти ?

Реализовать нормально версионность и использовать контракты

Ты понимаешь глубину глубин.

А ты — нет

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

А тебе рассказываю про элегантные архитектурные приемы, которые единообразно и просто решают не только те проблемы которые уже известны, но и те проблемы которые ты ещё даже не подозреваешь.

Мне больше интересно почему им 403 не подошло

Могу предположить что в этом случае до вызова процесса авторизации просто не доходит, реквест фильтруется до этого — чтобы различить эти кейсы.

Какое то сраное чучело, не имеющее отношения к программированию написало дисер при царе-пи**се, миллионы обезьянок подхватило и теперь уже хз сколько лет вместо того чтобы делать работу сидят думают по полдня что им возвращать 307 или 308.

Це хароший наброс, але він тільки показує твою недалекість

Увы, новому поколению уже не понять, что программирование не родилось год назад, ему десятки лет, и то что работало до этого, и то что будет работать после — НИЧЕМ не хуже. В отличие от безумного фанатичного поклонения какой-то моде как «правильно» писать API.

Кто умеет в корпоративную бизнес-логику, смотрит на эти модные потуги как полковник спецназа на гей-парад.

Дивишся на статус 200 — розумієш що все ок. На статус 401 — що авторизація не пройшла(і апі клієнти це теж показують по коду), 400 — ти неправильно сформував запит. 500 — не твоя вина.

Хіба це не прекрасно?

Убери 400 и добавь 403 и 404 и на этом стоп. Не нужно этим злоупотреблять. Если грузовик проехал 2/3 маршрута и внезапно закончился бензин не нужно натягивать на это какой-то хттп-код. Никаких кодов, методов и их пермутаций не хватит описать даже самый простенький бизнес.

400

что это вообще нахрен значит? фреймворк либо прибиндит модель либо не прибиндит — ничего bad request там не будет. я правда видел часто чудаков, что при неотловленном эксепшене возвращают 400. но я бы отдавал 500 в таком случае.

Після байдингу є валідація. Якщо вона фейлить то 400, і в боді деталі.

Само собой, как вариант. На 10 разных проектах будет 10 разных интерпретаций.

Подписаться на комментарии