вторник, 28 мая 2019 г.

Еще одно открытие


Больше двенадцати лет назад в этом блоге появилась моя первая публикация. Даже не одна, а несколько. Это былы небольшие статьи которые описывала мои первые шаги, как программиста, мой первый проект, и тот опыт который я вынес принимая в нем участие. Мне тогда очень хотелось написать об этом первом опыте, так как казалось что это будет не только полезно для себя самого сохранить эти воспоминания о событиях и эмоциях, которые я пережил в то время, но также интересно и для других людей почитать об этом.
Тогда еще не были настолько популярны подобные блоги и у меня по правде говоря не было каких то глобальных планов касательно него. Но после того как первая статья была написана, стало понятно, что все о чем я хотел написать, не поместилось в одну публикацию, поэтому пришлось писать еще одну. А за ней и еще одну. После этого появилась мысль написать не о своем опыте и размышениях а что то более прикладное. Тогда я интересовался функциональными языками, поэтому появилась статья о фуникциональном подходе в программировании и языках, популярных на то время. Получилось неплохо как мне показалось и тогда я решил развивать этот опыт и дальше.
Так дело двигалось дальше, я продолжал писать статьи в свое свободное время на интересующие меня темы. Постепенно вместе со своими статьями стали появлятся и переводы других статей. Я находил англоязычные статьи, которое казались мне интересными и переводил их. В то время я был активным пользователем сети RSDN, которая тогда как мне кажется переживала свои лучшие времена и была отличнейшим местом для общения программистов. Я часто делился ссылками на свои статьи и учавствовал в из обсуждении.
Я писал о том что мне было интересно в тот конкретный момент. Например, одно время я заинтересовался вопросами обфускации кода и даже написал свой обфускатор Orange Heap. На эту тему у меня был целый цикл статьей. Я детально описал как работают обфускаторы, какие бывают, какие основные приниципы преобразования кода, переименования и шифрования имен переменных и ресурсов. Кроме обфускации были статьи посвященные CSS. Я прочитал книгу которая посвящена основам CSS  и пришлось писать две статьи (здесь и здесь) которые были эдаким кратким конспектом, выжимкой основных приницов. Позже я много раз обращался к этим статьям и использовал из в качестве reference-литературы.
В одно время у меня появилась мысль писать как минимум по одной статье в месяц. Так оно и случилось – начиная с 2010 года я каждый месяц писал по статье. Но по правде говоря сейчас это уже чаще были переводы чем собстственные статьи. Я находил публикации которые мне были интересны, переводил их и публиковал у себя в блоге. Интересный момент, что вот теперь просматривая эти публикации можно четко увидеть как я развивался, чем интересовался и какие технологии использовал. Так изначально я был  .NET/WinForm/SQL разработчиком, потом к этому добавился WPF/Silverlight, потом закончился Silverlight, начался ASP.NET. Потом все меньше стало ASP.NET и больше JavaScript и TypeScript Начали появлятся интересы к JS-фреймворкам. Jquery, потом Angular, React. Вместе с этим были статьи которые относились к общим вопросам программирования: структурным, организационным, мотивационным.
Со временем блог мне дал очень многое. Каджый раз когда я изучал или только интересовался чем то новым я делал публикацию на эту тему, или хотя бы перевод англоязычной статьи по данной тематике. Таким образом у меня был сжатый конспект по данному вопросы, к которому я мог обращатся (и обращался) в последствии. В довесок к этому конспект был доступен онлайн любому челоеку который также инересовался  данной тематикой. Еще со времен активного использования RSDN у меня была достаточно большая аудитория читателей. В пике доходило до десятков тысяч уникальный читателей в месяц, а в среднем не менее полутора-двух тысяч.
Но чем дальше шло время, тем сложнее мне стало находить время на написание статей. Личная обязанность писать каждый месяц порой служила мне злую службу и я судорожно искал что-нибудь коротенькое и не совсем бессмысленное, что я смог бы перевести и опубликовать за час. Нормальная хорошая статья требует много времени, а у меня его почти всегда не хватало. К слову не хватает и сейчас. Поэтому как мне кажется со временем смысла в публикациях стало меньше. И для читателей и для меня. Очень часто стали появлятся статьи вида “Что нового в новой версии XXX” или “Топ 5 самых крутых фреймворков/подходов/направлений”. Оно то конечно может и полезно, но как мне кажется немного бессмысленно, так как публикация становилась блеклой копией прес-релиза новой версии продукта, о котором можно почитать абсолютно везде, либо вообще бессмысленным список топ-5 (топ-10/20) которые часто никому не были нужны и не несли ничего полезного.
Поэтому я решил отказатся от подобной практики. Настало время признатся себе, что если нечего писать то и писать не стоит. Не стоит выдавливать из себя публикацию если нет времени, интереса и желания. Жизнь изменчива и иногда действительно нету времени ни на что. Поэтому писать только для галочки, что в этом месяце статья есть – бессмысленно. И я так делать не буду. Вот поэтому когда я соберусь и напишу что то еще – я не знаю. Может быть завтра а может и через год. Но так или иначе – если это случится, то публикация будет действительно полезной и я точно уверен в том, что мне будет это интересно. 
Так что до новых встреч. И как говорил небезизвестный герой шоу Трумана:

  "In case I don't see you: good afternoon, good evening, and goodnight!"

Хорошего всем дня!

вторник, 30 апреля 2019 г.

Добавляем React.js в существующее asp.net приложения


Добавляем React.js в существующее asp.net приложения

Было время, когда если вы хотели что бы ваше приложение было более динамическим и менее разговорчивым в плане общения с сервером, вы моглы добавить ссылку на jQuery и это все чем вы могли пользоваться.
Потом появился Angular 1, который был призван решить те же проблемы.
Что бы дальше? Ну дальше было все немного сложнее.
Angular 2 привнес намного больше новых возможностей и вместе с ними, сделал все намного сложнее.
TypeScript, пре-рендеринг на сервере,  webpack
Если вы тратили много времени на работу с MVC/WebForms (или вовсе на десктопные приложения), то внезапно вы остаетесь сражатся что бы остаться на месте под солнцем.
Итак как же взабраться на гору .js когда вы все еще внизу?

Вы можете добавить React в существующее приложение.

Ссылка на скрипты React

В вашем приложении понадобятся как минимум два скрипта...
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
Этот код нужно добавить в <head>.
В моем примере ASP.NET Core app, я добавил это в Views/Shared/Layout.cshtml.
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - WebApplication1</title>

    <!-- other code here -->
   
    <script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
</head>
Теперь вы уже можете писать React компонент. Для этого добавьте .js куда то в wwwroot.
Вот ваш первый код!
var e = React.createElement;

class HelloWorld extends React.Component {
    render() {
        return e(
            "div",
            null,
            "Hello World"
        );
    }
}
const containerElement = document.getElementById('content');
ReactDOM.render(e(HelloWorld), containerElement);
Возможно код выглят слегка странно, если вы раньше не работали с React, но он просто создает div который говорит вам “Hello World”.
Как только мы реализовали компонент HelloWorld, мы можес его отрисовать.
Последние две строчки кода находят существующий элемент #content на вашей странице и внутри него отрисовывает компонент HelloWorld.
Теперь вы можете добавить ссылку на этот файл в вашем приложении и протестировать что React действительно добавил компнент Hello World на страницу.
Для данного примера я просто добавил компонент внизу страницы.
<h1>This is an exciting page in my existing application</h1>
<div id="content" />
<script src="~/js/hello.js"></script>

Но это не выглядит тем React, про который я читал в интернете?!

Вы правы, не выглядит.
В наши дни большинство самых первых примеров React выглядят так:
class HelloWorld extends React.Component {
    render() {
        return <div>Hello World</div>;
    }
}
const containerElement = document.getElementById('content');
ReactDOM.render(<HelloWorld />, containerElement);
Этот тэг <div></div>  является не чем иным как JSX.
И выглядит подозрительно похожим на HTML, не так ли? Но нет.
В реальности это javascript который создает html тэг div и добавляет его на страницу.
Фактически, он создаст код в точности такой как описано выше.
React.createElement(
    "div",
    null,
    "Hello World"
);
Для большинства из нас, создавать компоненты с JSX гораздо проще чем без него.
Но преобразование JSX в javascript не проходит автоматически, и требует дополнительных действий.
Если вы уже попробовали добавить JSX на вашу страницу то наверняка получили ошибку.

Браузер не может обработать jsx.

JSX это невалидный javascript. Как результат, браузер понятия не имеет что с этим делать.
Преобразовать...
<div>Hello World</div>;
в...
React.createElement(
    "div",
    null,
    "Hello World"
);
Для этого нам потребуется Babel.
Babel это javascript компилятор. Его главная задача – это взять современный javascript и скомпилировать его в javascript который поддерживается в том числе и более старыми браузерами.
Также этот компилятор используется что ыб преобразовать JSX в JS.
Вы можете попробовать сделать это самостоятельно здесь. Попробуйте вставить этот код

<div>Hello World</div>;
И посмотрите какой javascript вы получите в результате.

Автоматически преобразовать ваши JSX файлы в JS

Очевидно, что вы не будете брать каждый ваш jsx файл и вставлять его на сайте Babel для того что бы получить javascript код.
Для автоматизации процесса компиляции вам необходимо загрузить и запустить Babel на своей машине.
Вам понадобится последняя версия node.js, которая будет установлена на вашей машине, поэтому возьмите ее если вы еще не сделали это.
Теперь откройте командную строку в корне вашего веб приложения, здесь вам нужно будет выполнить несколько комманд, для того что бы добавить babel в ваше приложение.
npm  это пакетный менеджер для Node, он обеспечивает удобный способ управлять зависимостями в вашем приложнии.

npm init -y
npm install babel-cli@6 babel-preset-react-app@3
Эти зависимости нужны только для компиляции JSX в JS.  Мы не будем использовать пэкеджі node как часть веб сайта.
Мы просто должны запускать babel на этапе разработки для компиляции js файлов.
Скрипты React  мы добавили на страницу отображения раньше и они по прежнему нужны нашему приложению для того что бы выполнять компоненты react которые мы добавляем на страницу.
В конечном счете, мы запустим маленькую полезную команду «следить за изменениями» наших jsx файлов, и компилировать их в js сразу же как изменения были сделаны.
npx babel --watch src --out-dir wwwroot/dist --presets react-app/prod
Npx – это исполнитель пакетов, который упрощает запуск инструментов, которые находятся в пэкедже.
Вместо того что бы набирать полный путь к babel.exe  (который вы можете найти в  node_modules  вашего проекта) вы можете просто написать npx babel  и сохранить себе время и силы.
В данном примере, я говорю бабелю смотреть за папкой src и сохранить скомпилированный результат в wwwroot/dist.
(Мой пример скомпилирован как ASP.NET Core проект, поэтому все что требуется отдавать браузеру  хранится в wwwroot).

Теперь когда я делаю какие-то изменения в файлах в src, то скомпилированная версия сразу же появится в wwwroot/dist.


Теперь я могу ссылаться на эти скомпилированные js файлы из моих страничек.
<h1>This is an exciting page in my existing application</h1>

<div id="content" />

<script src="~/dist/hello.js"></script>

Завершение

Вы можете создавать React компоненты, писать их используя JSX и добавлять их на ваши страницы в вашем существующем приложении.
Очевидным недостатком данного подхода является то, что нужно не забывать запускать команду npx watch  когда вы работаете с приложением.


четверг, 28 марта 2019 г.

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


Вы будете использовать ружьё для того  чтобы застрелить муху? Разумеется нет. Тот же принцип следует использовать когда вы пишете приложение микросервиса, размер которого не будет превышать 10К строк кода. Не делайте код избыточным. Допустим у вас есть большой код который вы поддерживаете. Это может быть 100К+ строк кода, но вам следует изменить вашим привычкам и начать думать по-другому. Эта публикация позволит вам приобщится к магии написания простого кода для микросервисов, который легко поддерживать. Предложения могут оказаться самоуверенными, но на практике это происходит в бизенесе за миллионы доларов.


TL;DR
Микросервисы это маленькие системы. Вы можете легко избавиться от MVC. Скажите нет ORM и пожалуйста не используйте все ваши знания о паттернах проектирования в микросервисах. Сконцентрируйтесь на производительности, читабельности кода и поддерживаемости, чего нет в старых правилах и паттернах. Паттерны были придуманы не для микросервисов.
Зачем писать микросервисы в первую очередь

Архитектура микросервисов, по моему мнению, призвана разбить один или несколько монолитов на множество небольших систем. Они более гибки в поддержке, разрабатываются независимо и в строгом соответствии с со своим предназначением. Эти маленькие системы ( поэтому из и называют «микро») должны фокусироваться только на своей бизнес задаче и делать это хорошо. Ключевым моментом здесь является «микро» - код не должен превышать 10К строк.
Поскольку они являются независимыми, то позволяют добавлять поддержку новых возможностей быстрей. Команда сборки не зависит от коммитов команды разработки. И то что будет отправлено в продакшен, никогда не сломает систему. Система станет более распределенной. Область изменений всегда контроллируется. Это и является причиной использования микросервисов.
Теперь давайте посмотрим на то, как вы создавали код раньше и почему в этом теперь мало смысла в эпоху микросервисов.


Вам нужен MVC?

С паттерном Модель-Представление-Контроллер (MVC) я познакомился в 2007 или может чуть раньше. С тех пор я думал что это серебрянная пуля для любой архитектуры программного обеспечения. Но больше я не придерживаюсь такого мнения. Да вы привыкли работать с Java или PHP и там любой фреймворк построен на MVC. Но теперь вам не обязательно думать что иначе не может быть. Сфокусируйтесь на чистоте и том, что бы все работало.
Используйте контроллеры если вы хотите и это уместно в вашем случае. Думайте о задаче в духе: мое приложение получает HTTP запрос и после возвращает HTTP ответ. Не думайте о том, что у вас есть бэкенд с API и фронтенд, который его использует. Посмотрите на этот код, это точно не MVC:
  async function get(params) {

  const today = new Date().toISOString().split('T')[0];
  const {fromCurrency='AUD', toCurrency='USD', onDate=today} = params;

  let exchangeRates = await db.query(
    `SELECT rate, created_at FROM exchange_rates WHERE from_currency = ? AND to_currency = ? AND on_date = ?`,
    [fromCurrency, toCurrency, onDate]
  );
   
  if (exchangeRates.length) {
    const rate = Number(exchangeRates[0].rate);
    console.log(`Found exchange rate of ${rate} for ${fromCurrency} to ${toCurrency} of ${onDate} in the db`);
    return {fromCurrency, toCurrency, onDate, rate};
  }
 
  return getExternal(fromCurrency, toCurrency, onDate);
}

module.exports = {
  get
}
Вы можете посмотреть полное приложение здесь, и обратите внимание, это точно не MVC.
Поэтому вместо того, что бы следовать каждой букве M-V-C, пишите тесты, реализуйте непрерывную интеграцию. Добавьте лог и прочие средства для мониторнига приложения. Пишите максимально простой код, который легко поддерживать.

Не переусердствуйте с ORM

Когда я впервые познакомился с ORM (Object Relation Mapping), я сказал сам себе что это самая крутая штука для программистов которую я видел. Спустя более чем 10 лет, я бы остерегался предлагать использовать ORM для любых случаев. Недавно я занимался рефакторингом и заменял реализацию полной ORM в чистыми вызовами SQL запросов. В результате я получил 20% прироста производительности. В дополнение к этому я начал непосредственно использовать транзакции и сделал код намного чище и понятней.
Маппер данных или Активная запись – каждая из них привностит свои особенности в реализации и тяжеловестноти решения. Это влияет не только на производительность, но также и на читабельность кода. Вот например возмем пре и пост хуки для Doctrine, они как то магически работают, и понять эту магию весьма не просто.
Вот просто попробуйте объяснить молодому специалисту как ORM добавляет данные и как данные добавляются с помощью INSERT SQL. Вы уже пожалели что используете ORM. И особенно в контексте микросервисов ORM выглядит чрезмерной. Микросервисы должны быть не более 10К строк кода, и использовать как максимум с десяток таблиц, поэтому не используйте ORM. Точка.

Паттерны проектирования могут быть обузой

Я ни в коем случае не говорю не изучать паттерны проектирования. Вы должы знать о SOLID, закона Деметры, паттерне фабрики, стратегии, синглтона, адаптера и прочих. Все это полезно если вы имеете дело с объектно –ориентированным программированием, верно? А что если вы пишете микросервис с помощью Node.js когда 1К сток кода разбиты на 7 файлов. Код просто решает некую бизнес задачу. Все эти паттерны для данного случая становятся не более чем полезной ерундой.
Паттерны проектирования полезны для кода, который уже большой и в ближайшие полгода станет еще больше, то есть нормальным таким монолитом. Паттерны подойдут для сервиса в 100 строк кода, которые в течение полгода превратятся в 1000 строк. Мы никогда не предполагаем, что размер кода будет больше, потому что для выполнения другой части у нас будет другой микросервис. Так что следите за тем, чтобы ваш код микросервиса был обезжиренным и хорошо проверенным.

Выводы

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