Страницы

среда, 17 апреля 2019 г.

Trying Clean Architecture on Typescript

В моей библиотеке книги Роберта Мартина занимают почетное место - на рабочем столе, рядом с публикациями Мартина Фаулера, Стива Макконнелла и еще нескольких менее известных авторов. Отзывы о его последней книге, Clean Architecture, неоднозначны: кому-то не хватает деталей, а кто-то просто пытается реализовать свое понимание усвоенного материала на своей любимой платформе. Недавно мне попалась на глаза одна такая попытка на Go, потом еще одна, потом еще одна на Python, и я решил попробовать написать что-то подобное на TypeScript.

пятница, 29 марта 2019 г.

Golang RESTful gRPC

Нельзя просто взять и написать структуры (классы) доступа к данным Protocol BuffersgRPC API начинается со спецификации. HTTP API может существовать и без спецификации. Тем не менее, по понятным причинам, трудно найти коммерческий HTTP API без какого-нибудь OpenAPI (он же Swaggerон же Гога, он же Жора). В экосистеме gRPC есть инструмент по имени grpc-gateway, который может оказаться очень полезным в случае необходимости "прикрутить" HTTP JSON API к gRPC API. Он позволяет генерировать код reverse-proxy, а также спецификацию в формате OpenAPI,  используя определения в файлах .proto, что упрощает как разработку, так и поддержку.

воскресенье, 10 февраля 2019 г.

Golang generics wanted

Вот уже несколько месяцев я пишу на Go и мне это нравится. Инструменты разработки просто супер. Visual Studio Code решает. Язык простойGo 2 в процессеМодули уже здесь, и судя по всему скоро станут еще лучше. Обработка ошибок после коллбэков не самое страшное. Сами по себе ошибки страшнее, но с помощью существующих сторонних решений можно как-то перетерпеть. А вот дженериков не хватает уже сейчас: дублировать код функций, создавать новые структуры там где нет никакой разницы какого типа аргумент или поле - занятие на любителя.

суббота, 20 октября 2018 г.

Sending binary with Node.js via gRPC

Protocol Buffers - протокол сериализации структурированных данных. Нельзя просто взять и скомпилировать: rpc Send (stream bytes) returns (void);, нужно обязательно использовать структуры: rpc Send (stream File) returns (Empty);. В Node.js самый простой способ отправить файл, или любой другой Readable Stream - спайпить его с Writable Stream. Для того чтобы отправить файл через gRPC можно пребразовать поток бинарных данных в поток структурированных данных и наоборот с помощью Transform Stream, как-то так: на клиенте Readable Stream -> Transform Stream -> ClientReadableStream, на сервере ServerReadableStream -> Transform Stream -> Writable Stream.

суббота, 28 июля 2018 г.

Node.js gRPC defaults

Вчера обновил grpc-node и после запуска приложения получил предупреждение: 'DeprecationWarning: grpc.load: Use the @grpc/proto-loader module with grpc.loadPackageDefinition instead'. В процессе выяснения причины оказалось что grpc-protobufjs среди прочих решает вопрос с дефолтными значениями: по умолчанию отсутствие значения интерпретируется как отсутствие значения, т.е. полю не присваивается дефолтное значение. Конец моим страданиям и разочарованиям, теперь можно избавляться от костылей. Кроме того исследование изменений в gRPC позволило мне ответить еще на один на вопрос: как передать метаданные с сервера на клиента без использования ошибки.

суббота, 17 марта 2018 г.

WTF with errors in gRPC?

Недавно мне задали вопрос: для чего нужен package-lock.json, я ответил: для того же для чего и npm-shrinkwrap.json - чтобы не было мучительно больно. Вчера обнаружил удивительный диссонанс между версиями 1.8.0 и 1.8.4 модуля gRPC, а именно изменения в процессе создания ошибки, вот от кого никак не ожидал. К примеру, если в версии 1.8.0 ошибка с сообщением 'Invalid name' на сервере предсказуемо превращалась в ошибку в таким же сообщением на клиенте, то в версии 1.8.4 на клиенте то же сообщение об ошибке превращается в '2 UNKNOWN: Invalid name'. WTF?

суббота, 24 февраля 2018 г.

Node.js Design Patterns

Сегодня дочитал второе издание Node.js Design Patterns. Очень полезное чтиво по разработке под Node.js, предыдущая версия в свое время мне тоже понравилась. Правда по ходу у меня появилось одно замечание, суть которого заключается в том, что автор вешает на процесс функцию слушателя события 'exit', которая является асинхронной, в то время как она должа быть синхронной, в противном случае у нас нет никаких гарантий в том, что эта функция выполнит свою миссию в полном объеме.

среда, 21 февраля 2018 г.

Mocha exclude node_modules

Для тестов в Node.js я использую mocha + assert, как говорится дешево и сердито. Если тесты лежат в отдельном каталоге, в package.json команда для их запуска как правило выглядит так: `mocha test/**/*.spec.js`, если рядом с исходниками, тогда как-то так: `mocha ./**/*.spec.js`. Только вот если в каталоге node_modules есть тесты которые попадают в глобальный паттерн, mocha их тоже выполнит, что на мой взгляд не всегда уместно. Исключить каталог node_modules можно следующим образом:

пятница, 19 января 2018 г.

JavaScript interview question

"Посетителю должно быть неудобно. Посетитель должен быть смешон. Иначе, какое от него удовольствие?", - братья Стругацкие"Обитаемый остров". Сегодня познакомился с задачей, которую можно использовать на собеседовании по JavaScript если вдруг появилось желание "сделать посетителю неудобно". Или собеседник знает в чем подвох, что маловероятно (вряд ли кто-либо использует подобные приемы на практике), или есть шанс получить процесс решения, который может кое-что рассказать о собеседнике. Не пытайтесь повторить это дома.

суббота, 9 декабря 2017 г.

Going to gRPC. Bidirectional streaming

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