Как работает query в REST?
#architecture #nestjs
Вопрос с собеседований: "Чему равно id во время выполнения такого запроса:
Какой ответ дадите вы?
- будет ошибка, нельзя использовать два раза один параметр
- 1, потому что first win
- 2, потому что last win
- [1, 2]
В списке нет правильного ответа. Согласно спецификации это должен быть массив, но массив строк, а не чисел. Приведение типов это не часть парсинга строки.
Для передачи массива параметров в query есть такие варианты:
1️⃣
2️⃣
3️⃣
4️⃣
Какой способ выбрать зависит от того какой framework или библиотеку вы используете. Для #nodejs разработчики использующих express ближе всего будет 2-й способ. По умолчанию express используют extended query parser, то есть использует qs. Эта библиотека учитывает
#architecture #nestjs
Вопрос с собеседований: "Чему равно id во время выполнения такого запроса:
?id=1&id=2"Какой ответ дадите вы?
- будет ошибка, нельзя использовать два раза один параметр
- 1, потому что first win
- 2, потому что last win
- [1, 2]
В списке нет правильного ответа. Согласно спецификации это должен быть массив, но массив строк, а не чисел. Приведение типов это не часть парсинга строки.
Для передачи массива параметров в query есть такие варианты:
1️⃣
?foo=bar&foo=qux2️⃣
?foo[]=bar&foo[]=qux3️⃣
?foo%5B%5D=bar&foo%5B%5D=qux4️⃣
?foo=bar,quxКакой способ выбрать зависит от того какой framework или библиотеку вы используете. Для #nodejs разработчики использующих express ближе всего будет 2-й способ. По умолчанию express используют extended query parser, то есть использует qs. Эта библиотека учитывает
[] при парсинге.Какие вопросы необходимо решить при внедрение WebSockets?
#architecture
Вот список вопросов, которые я задаю при внедрение WS на проекте.
❓ Какую бизнес задачу решают real-time updates от сервера? Определяет нужны WS, SSE или GraphQL Subscriptions.
❓ Какие клиенты будут использоваться: браузер, мобильные и т.д? Определяет нужен ли fallback, если WS не доступен. Ключевой аргумент в извечном споре socket.io VS ws
❓ Может ли клиент подписываться на конкретный поток сообщений? Определяет механизм создания подписок и поведения в момент пере-подключения.
❓ Какие ACL нужны? Определяет поведения системы в момент подключения, отправки/принятие сообщений и создание подписок.
❓ Где мы разворачиваем? Определяет перечень технологий, которые мы сможем использовать. Например, в AWS есть WS на serverless.
#architecture
Вот список вопросов, которые я задаю при внедрение WS на проекте.
❓ Какую бизнес задачу решают real-time updates от сервера? Определяет нужны WS, SSE или GraphQL Subscriptions.
❓ Какие клиенты будут использоваться: браузер, мобильные и т.д? Определяет нужен ли fallback, если WS не доступен. Ключевой аргумент в извечном споре socket.io VS ws
❓ Может ли клиент подписываться на конкретный поток сообщений? Определяет механизм создания подписок и поведения в момент пере-подключения.
❓ Какие ACL нужны? Определяет поведения системы в момент подключения, отправки/принятие сообщений и создание подписок.
❓ Где мы разворачиваем? Определяет перечень технологий, которые мы сможем использовать. Например, в AWS есть WS на serverless.
Как документировать асинхронное API?
#architecture #service
TL;DR Используйте AsynAPI
Упрощенно говоря существует только два способа взаимодействия: Req/Res и Pub/Sub. Еще эти способы называют синхронный и асинхронный.
При Request/Response клиент отправляет запрос на сервер, сервер начинает работу и отправляет ответ клиенту, как только работа будет выполнена. При Publish/Subscribe вместе запроса публикуется событие и ответ не требуется. Некоторые buzzword используемые при PubSub: WebHooks, Event-driven architectures, CQRS.
REST является классическим способом создания Web API и реализует Req/Res взаимодействие. Для его описания традиционно используют OpenApi, старое название Swagger.
Через WebSockets является дву-направленным протоколом, что позволяет создавать на его основе как Req/Res, так и Pub/Sub взаимодействие. Чаще всего WS используют именно для оповещений со стороны сервера, т.е для Pub/Sub. Естественно его следует описывать, использовать Documentation First подход. Для этого и был создан AsynAPI. Он позволяет описывать асинхронное взаимодействия не только по WS, но и по другим протоколам. Рекомендую к использованию.
#architecture #service
TL;DR Используйте AsynAPI
Упрощенно говоря существует только два способа взаимодействия: Req/Res и Pub/Sub. Еще эти способы называют синхронный и асинхронный.
При Request/Response клиент отправляет запрос на сервер, сервер начинает работу и отправляет ответ клиенту, как только работа будет выполнена. При Publish/Subscribe вместе запроса публикуется событие и ответ не требуется. Некоторые buzzword используемые при PubSub: WebHooks, Event-driven architectures, CQRS.
REST является классическим способом создания Web API и реализует Req/Res взаимодействие. Для его описания традиционно используют OpenApi, старое название Swagger.
Через WebSockets является дву-направленным протоколом, что позволяет создавать на его основе как Req/Res, так и Pub/Sub взаимодействие. Чаще всего WS используют именно для оповещений со стороны сервера, т.е для Pub/Sub. Естественно его следует описывать, использовать Documentation First подход. Для этого и был создан AsynAPI. Он позволяет описывать асинхронное взаимодействия не только по WS, но и по другим протоколам. Рекомендую к использованию.
Asyncapi
AsyncAPI Initiative for event-driven APIs
Open source tools to easily build and maintain your event-driven architecture.
All powered by the AsyncAPI specification, the industry standard for defining asynchronous APIs.
All powered by the AsyncAPI specification, the industry standard for defining asynchronous APIs.
Что такое Breaking Change в Web API?
#architecture
Обратная совместимость (backward compatibility) одно из ключевых требований при выборе инструментов, библиотек, API и т.д. Нарушение обратной совместимости называет Breaking Change.
Примеры Breaking Change:
❌ Переименование полей. Добавьте новое, но оставьте старое.
❌ Изменение типа поля.
❌ Изменение http-кода ответа, например с 400 на 404. В REST приложениях клиент должен строит логику на основание этих кодов.
❌ Изменение значений по умолчанию. Например, раньше API отдавало все записи, а теперь только первые 50 элементов.
Команда разработки может игнорировать обратную совместимость, только если проект состоит из API и Single Page Application, которые доставляются одновременно. Если среди клиентов есть мобильное, десктоп приложение, то функциональность будет сломана пока пользователь не обновить приложение.
Хорошими практиками является версионирование API и пометка как deprecated для полей и endpoints. Если клиент использует версию старше, чем предоставляет сервер, то он может уведомить пользователя об необходимости обновления ПО.
#architecture
Обратная совместимость (backward compatibility) одно из ключевых требований при выборе инструментов, библиотек, API и т.д. Нарушение обратной совместимости называет Breaking Change.
Примеры Breaking Change:
❌ Переименование полей. Добавьте новое, но оставьте старое.
❌ Изменение типа поля.
❌ Изменение http-кода ответа, например с 400 на 404. В REST приложениях клиент должен строит логику на основание этих кодов.
❌ Изменение значений по умолчанию. Например, раньше API отдавало все записи, а теперь только первые 50 элементов.
Команда разработки может игнорировать обратную совместимость, только если проект состоит из API и Single Page Application, которые доставляются одновременно. Если среди клиентов есть мобильное, десктоп приложение, то функциональность будет сломана пока пользователь не обновить приложение.
Хорошими практиками является версионирование API и пометка как deprecated для полей и endpoints. Если клиент использует версию старше, чем предоставляет сервер, то он может уведомить пользователя об необходимости обновления ПО.
Как правильно проектировать обновление в REST?
#rest #architecture
Вот, что следует учесть при проектирование endpoint-ов, которые будут обновлять состояние ресурсов:
❓Необходимо полное (PUT) или частичное обновление (PATCH)? Возможно, необходимы оба способа. В блоге Postman на этой неделе была статья What We Learned from 200,000 OpenAPI Files. Из нее можно увидеть, что в среднем PUT используется в 10 раз чаще чем PATCH.
❓Должен ли сервер проверять, что клиент использует последнюю версию ресурса? Если это необходимо, то необходимы заголовки Etag и If-Match. Если версия ресурса описанная Etag-м на клиенте и сервере отличается, то сервер выдаст ошибку с 412 кодом (Precondition Failed).
❓Что мы редактируем, сущность или коллекцию сущностей? Для редактирования отдельной сущности (
#rest #architecture
Вот, что следует учесть при проектирование endpoint-ов, которые будут обновлять состояние ресурсов:
❓Необходимо полное (PUT) или частичное обновление (PATCH)? Возможно, необходимы оба способа. В блоге Postman на этой неделе была статья What We Learned from 200,000 OpenAPI Files. Из нее можно увидеть, что в среднем PUT используется в 10 раз чаще чем PATCH.
❓Должен ли сервер проверять, что клиент использует последнюю версию ресурса? Если это необходимо, то необходимы заголовки Etag и If-Match. Если версия ресурса описанная Etag-м на клиенте и сервере отличается, то сервер выдаст ошибку с 412 кодом (Precondition Failed).
❓Что мы редактируем, сущность или коллекцию сущностей? Для редактирования отдельной сущности (
/todos/:id) подойдут и PUT, и PATCH. Но при редактирование коллекции (/todos/) стоит использовать PATCH с body в формате JSON Patch.Как выстрелить себе ногу с помощью microservices?
#architecture
Сегодня рецептик в стиле вредных советов, специально для тех, кто хочет осознано завалить проект.
⚠️ Начинайте новый проект сразу на микросервисах. Monolith first устарел
⚠️ Начиная со второго микросервиса внедрите распределенные транзакции.
⚠️ Оставьте бизнес домен бизнесу. Микросервисы не должны иметь связь с бизнес доменом, вместо этого делайте их универсальными. DDD не для инженеров.
⚠️ Не задумывайтесь об версионирование. Версионирование данных, контрактов, микросервисов, всей системы в целом – возникнет само.
⚠️ Избегайте инструментов для оркестрирования (Kubernetes, Istio и т.д.). Они только усложняют работу. Делайте все на уровне кода, а не на уровне инфраструктуры.
⚠️ Микросервисы созданы, чтобы пробовать новые технологии. Поэтому чем больше у вас будет новых технологий, тем лучше! Каждый новый микросервис – новый фреймворк, а лучше язык!
#architecture
Сегодня рецептик в стиле вредных советов, специально для тех, кто хочет осознано завалить проект.
⚠️ Начинайте новый проект сразу на микросервисах. Monolith first устарел
⚠️ Начиная со второго микросервиса внедрите распределенные транзакции.
⚠️ Оставьте бизнес домен бизнесу. Микросервисы не должны иметь связь с бизнес доменом, вместо этого делайте их универсальными. DDD не для инженеров.
⚠️ Не задумывайтесь об версионирование. Версионирование данных, контрактов, микросервисов, всей системы в целом – возникнет само.
⚠️ Избегайте инструментов для оркестрирования (Kubernetes, Istio и т.д.). Они только усложняют работу. Делайте все на уровне кода, а не на уровне инфраструктуры.
⚠️ Микросервисы созданы, чтобы пробовать новые технологии. Поэтому чем больше у вас будет новых технологий, тем лучше! Каждый новый микросервис – новый фреймворк, а лучше язык!
Что такое Fetch Event Source?
#package #architecture
На канале был рецепт Что такое Race Condition на клиенте? В нем я рекомендовал использовать Server Sent Events. Это однонаправленный протокол от сервера к клиенту. Является отличной альтеранативой websocket-ам, которые являются двунаправленным протоколом.
На сервере все достаточно просто. Например, в Nest.js есть хорошая документация – server-sent-events. На клиенте все не так просто – у нативного браузерного
#package #architecture
На канале был рецепт Что такое Race Condition на клиенте? В нем я рекомендовал использовать Server Sent Events. Это однонаправленный протокол от сервера к клиенту. Является отличной альтеранативой websocket-ам, которые являются двунаправленным протоколом.
На сервере все достаточно просто. Например, в Nest.js есть хорошая документация – server-sent-events. На клиенте все не так просто – у нативного браузерного
EventSource API есть ряд ограничений: нельзя передавать custom headers, только Get. Правильной альтернативой является пакет @microsoft/fetch-event-source. Он одновременно обладает всеми фишками fetch и Server Sent Events. Рекомендую к использованию и сам протокол SSE, и клиентский пакет от microsoft. Кто знает, вдруг эту реализацию сделают встроенной в браузерные API.👍12
Architecture decisions records?
#architecture
Гарною інженерною практикою є документування прийнятих тех рішень – Architecture Decision Records (ADR). Це можуть бути зміни в технічному стеку, вибір технології, спосіб оплати технічного боргу та інше. Така документація допомагає зрозуміти, чому так склалося історично. Для ADR можна використовувати різні інструменти. Мій особистий вибір log4brains.
Посилання:
🔗 ADR
🔗 log4brains
#architecture
Гарною інженерною практикою є документування прийнятих тех рішень – Architecture Decision Records (ADR). Це можуть бути зміни в технічному стеку, вибір технології, спосіб оплати технічного боргу та інше. Така документація допомагає зрозуміти, чому так склалося історично. Для ADR можна використовувати різні інструменти. Мій особистий вибір log4brains.
Посилання:
🔗 ADR
🔗 log4brains
👍22❤2
Як організувати "multi time zone" функціонал?
#architecture
Одна зі стандартних вимог для глобальних веб-проектів – це підтримка часових поясів.
1️⃣ Для полегшення архітектури краще використовувати такий поділ відповідальності:
👉 Веб сервер відповідає за обробку та передачу даних в UTC.
👉 Веб клієнт відповідає за відображення date-time у необхідній користувачеві таймзоні та календарі. Нагадаю, що існують країни, які використовують не Григоріанський календар.
⚠️ цей підхід не прибирає потреби у сервера працювати з часовими поясами.
2️⃣ Визначається точність виміру часу. Стандартно це мілісекунди.
3️⃣ Визначається dto serialization (формат передачі у API) для таких сутностей
👉 момент часу. Unix Timestamp (
👉 часовий пояс. Ім'я (
👉 конкретна дата. ISO 8601(
👉 Тривалість. ISO 8601 format (
👉 Інтервал часу. Як два моменти часу (початок та кінець), або як початок та тривалість, або як один рядок (
Всі прийняті рішення є частиною специфікації вашого API
4️⃣ Визначається на рівні коду або на рівні бази даних відбуватиметься маніпуляція з datetime та timezone. Приклад: клієнт запитує транзакції користувача за
#architecture
Одна зі стандартних вимог для глобальних веб-проектів – це підтримка часових поясів.
1️⃣ Для полегшення архітектури краще використовувати такий поділ відповідальності:
👉 Веб сервер відповідає за обробку та передачу даних в UTC.
👉 Веб клієнт відповідає за відображення date-time у необхідній користувачеві таймзоні та календарі. Нагадаю, що існують країни, які використовують не Григоріанський календар.
⚠️ цей підхід не прибирає потреби у сервера працювати з часовими поясами.
2️⃣ Визначається точність виміру часу. Стандартно це мілісекунди.
3️⃣ Визначається dto serialization (формат передачі у API) для таких сутностей
👉 момент часу. Unix Timestamp (
1675096836070) або рядок у форматі ISO 8601 (2023-01-30T16:37:12.661Z)👉 часовий пояс. Ім'я (
Europe/Kyiv)👉 конкретна дата. ISO 8601(
2023-01-30) або момент часу коли почалась ця дата або як інтервал часу.👉 Тривалість. ISO 8601 format (
12H30M5S) або кількість мілісекунд.👉 Інтервал часу. Як два моменти часу (початок та кінець), або як початок та тривалість, або як один рядок (
2023-01-01T13:00:00Z/2023-01-01T15:30:00Z)Всі прийняті рішення є частиною специфікації вашого API
4️⃣ Визначається на рівні коду або на рівні бази даних відбуватиметься маніпуляція з datetime та timezone. Приклад: клієнт запитує транзакції користувача за
2023-01-30 у таймзоні Europe/Kyiv. Особисто я перекладаю відповідальність фільтації на базу даних.👍30🔥12
Які типи запуску може мати Serverless?
#architecture #aws
Нагадаю базові речі, будь-який serverless будується на основі на Docker. Якщо це функції, лямбди, тобто Serverless Function, то Cloud вендор надає вам Docker Image куди платформа додасть ще один layer із вашим кодом. Якщо це Serverless Container, то запускатиметься той Docker Image, який ви дали. В обох випадках запускається саме докер-контейнер.
Приклади Serverless functions:
👉 AWS Lambda
👉 Azure Functions
👉 Cloud Functions
Приклади Serverless container:
👉 AWS Fargate
👉 Azure Container Instances
👉 Google Cloud Run
Тип запуску визначається саме станом контейнера:
❄️ Холодний старт (Cold Start) - це процес запуску у серверлес-середовищі, коли контейнер не існує та Docker Image відсутній. При такому запуску відбувається ініціалізація середовища та завантаження Docker Image, що призводить до затримок у відповіді на запити.
☀️Теплий старт (Warm Start) - це стан, коли серверлес-середовище має наявний Docker Image, але потрібно створити новий Docker Container. Під час запуску контейнера додаток може підключатися до бази даних та інших необхідних ресурсів.
🔥Гарячий старт (Hot Start) - це стан, коли Docker Container залишається активним у серверлес-середовищі після обробки попередніх запитів. Це найшвидший стан, оскільки контейнер вже повністю завантажений і готовий до негайного виконання наступних запитів.
Саме тому я використовую не прогрівання Serverless Functions, а Servless Container, який може бути викликаний не одним, а кількома тригерами, тому частіше перебуває у гарячому чи теплому стані.
⚠️ Рецепт написаний, як пояснення чому суттєвого прискорення shared Lambda layers у разі холодного старту ваших AWS лямд не дає.
#architecture #aws
Нагадаю базові речі, будь-який serverless будується на основі на Docker. Якщо це функції, лямбди, тобто Serverless Function, то Cloud вендор надає вам Docker Image куди платформа додасть ще один layer із вашим кодом. Якщо це Serverless Container, то запускатиметься той Docker Image, який ви дали. В обох випадках запускається саме докер-контейнер.
Приклади Serverless functions:
👉 AWS Lambda
👉 Azure Functions
👉 Cloud Functions
Приклади Serverless container:
👉 AWS Fargate
👉 Azure Container Instances
👉 Google Cloud Run
Тип запуску визначається саме станом контейнера:
❄️ Холодний старт (Cold Start) - це процес запуску у серверлес-середовищі, коли контейнер не існує та Docker Image відсутній. При такому запуску відбувається ініціалізація середовища та завантаження Docker Image, що призводить до затримок у відповіді на запити.
☀️Теплий старт (Warm Start) - це стан, коли серверлес-середовище має наявний Docker Image, але потрібно створити новий Docker Container. Під час запуску контейнера додаток може підключатися до бази даних та інших необхідних ресурсів.
🔥Гарячий старт (Hot Start) - це стан, коли Docker Container залишається активним у серверлес-середовищі після обробки попередніх запитів. Це найшвидший стан, оскільки контейнер вже повністю завантажений і готовий до негайного виконання наступних запитів.
Саме тому я використовую не прогрівання Serverless Functions, а Servless Container, який може бути викликаний не одним, а кількома тригерами, тому частіше перебуває у гарячому чи теплому стані.
⚠️ Рецепт написаний, як пояснення чому суттєвого прискорення shared Lambda layers у разі холодного старту ваших AWS лямд не дає.
👍42❤4