Вступление

В первых двух частях этой серии мы реализовали нашу идею и подготовили базовый интерфейс для адаптивного веб-приложения. Честно говоря, подготовка этой части заняла больше времени, чем я надеялся, потому что меня отвлекли, когда я начал новую работу… :-) Я чувствую, что некоторые моменты, которыми я хотел поделиться, ускользнули от нас, так что это тур будет быстрее, чем ожидалось.

Нажмите здесь, чтобы опубликовать эту статью в LinkedIn »

На всякий случай, если вы забыли, вот план нашей серии Идея для приложения:

Изначально я планировал также раздел Развертывание… но решил, что это будет последняя часть в этой серии. Возможно, я коснусь аспектов развертывания типичных веб- и мобильных приложений в будущих сериях. ChowChow - это простое приложение, развернутое на Heroku, так что особо не о чем рассказать, чего нет в их превосходных документах!

Чтобы компенсировать это, на основе того, насколько хорошо мне удается распределять время между работой (SRE - это достаточно весело, часто трудно оторваться!), Фактическое программирование, изучение новых вещей и ведение блога ... более интересная тема, возможно, возвращается назад наше готовое приложение и рефакторинг (добавить больше обработки ошибок, лучше использовать новые функции ES, такие как обещания, очистка на основе Руководства по стилю Airbnb и т. д.).

Не забудьте клонировать репозиторий, чтобы продолжить…

Использование окружающей среды

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

Использование среды не ограничивается конфиденциальной информацией, которую вы не хотите проверять в системе контроля версий ... ее также можно передать для управления поведением (например, dev vs prod) или для чтения динамической информации, такой как адрес прослушивания. В Node.js мы используем для этого process.env.

ChowChow достаточно прост, и нам не о чем беспокоиться, но нам нужно прочитать IP-адрес и порт из среды (так что все работает на моем ноутбуке, а также у моего хостинг-провайдера). У нас также есть секретный ключ, используемый экспресс-сессией (обеспечивает легкое управление сессией).

Специальный адрес 0.0.0.0 просто прослушивает все доступные интерфейсы (которые могут быть домашним шлейфом или адресом Ethernet моего портативного компьютера или виртуальным сетевым адаптером контейнера на платформе вроде Heroku). Я мог бы установить для этого параметра 127.0.0.1, и он будет работать так же легко дома, но это обычно ломается при доставке приложения, поэтому 0.0.0.0 легче управлять. Если вас беспокоит привязка ко всем доступным интерфейсам на вашем портативном компьютере (надеюсь, вы используете брандмауэр), вы можете использовать 127.0.0.1, а затем установить переменную среды IP при запуске. PORT очень похож, поэтому я не буду останавливаться на нем, просто обратите внимание, как вы можете передать переменную среды PORT или оставить значение по умолчанию 3000. Вы могли бы установить их через оболочку как export NAME = value или, возможно, какой-нибудь механизм вроде config vars Heroku.

И последнее, но не менее важное: secret по умолчанию будет some random string, чтобы упростить разработку, но для производства мы установим переменную среды SECRET в нашей среде, контейнере, инструменте сборки или хостинг-провайдере ... таким образом, настоящий секрет не проверяется в GitHub . Легко, правда?

Dev vs Production

Мне очень нравится изучать Экспресс, но если вы отправляете настоящее приложение, то первое, что вам нужно изменить (это не секрет, все документы ясно дают понять!), - это экспресс-сессия. MemoryStore. Это отличная отправная точка для создания прототипов, но в процессе производства будет происходить утечка памяти (насколько я понимаю, срок ее действия не имеет значения).

Существует ТОННА опций для резервного хранилища (например, вы можете захотеть, чтобы сеансы сохранялись в MongoDB или базе данных SQL), но, придерживаясь нашей темы простоты, memorystore работает очень похоже на стандартное хранилище без утечек памяти. . Идеально! Давайте настроим это для ChowChow:

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

ПО промежуточного слоя

Как упоминалось ранее в этой серии, технологическим стеком, который мы выбрали для этого эксперимента, были Node.js и Express… В этой экосистеме общей темой является сохранение кода, ответственного за маршруты, чистым путем факторизации функций, выполняющих тяжелую работу, в промежуточное ПО.

Вы можете объединить функции промежуточного программного обеспечения в цепочку для обеспечения гибкости, передавая результаты через сеанс или возвращаемые значения. Давайте посмотрим на простой пример этого в нашем приложении ... во-первых, в app.js маршрут /random, отвечающий за отображение случайно выбранного ресторана рядом с пользователем, выглядит довольно чистым:

Мы могли бы просто сделать наш app.post маршрут, содержащий всю логику m.logRequest и m.parseRequest, но это усложнит чтение кода и вызовет большое количество дублирования (не очень СУХОЙ!) Для таких вещей, как logRequest, которые в настоящее время разделяют все наши маршруты. .

Давайте углубимся в parseRequest

API Wrangling

Основная часть нашей функциональности исходит из Yelp Fusion API. Плохо названный parseRequest (честно говоря, в то время это казалось хорошим названием по причинам, которые код мог прояснить; если нет, добавьте элемент в наш список рефакторинга!) Является промежуточным программным обеспечением отвечает за обработку входных данных нашего приложения (такие как широта и долгота, полученные из geolocation, обсуждаемые в предыдущей части этой серии) и получение результатов API.

Это все еще длиннее, чем мне хотелось бы, даже после выделения нескольких строк во вспомогательную функцию, но вот посмотрите на parseRequest в его нынешнем виде:

Это создает необходимую строку запроса, которая требуется API Yelp для поиска еды рядом с пользователем ... Стоит отметить, что q назначение становится немного более управляемым за счет использования шаблонных литералов.

Когда у нас есть подходящий запрос, мы вызываем searchYelp с обратным вызовом (это может занять некоторое время), чтобы получить наши результаты ... если случаются непредвиденные вещи, мы используем де-факто connect-flash для отображения сообщений пользователю, записывая в сеанс (если вы клонировали репо, вы можете увидеть пример того, как это отображается в home.ejs в error div).

Все это довольно стандартно (единственный трюк - использование фильтра), поэтому давайте подведем итоги, взглянув на searchYelp:

Сначала мы создаем объект options, чтобы управлять поведением https.get. Большинство из них - простые const далее в файле, но APIKEY считываются из среды (в конце концов, это конфиденциальные данные, которые мы не хотим регистрировать в git!) Через знакомый process.env.API_KEY.

Самая интересная (возможно?) Часть этого - использование https.get. Мы могли бы использовать любое количество вариантов для этого запроса ... моим первым побуждением было использовать что-то знакомое (изученное в классе); Модуль запроса. Помимо того, что она наиболее знакома, она также похожа на библиотеку запросов Python. Один реальный недостаток нашего приложения (попытка оптимизации для простоты) - это огромное количество зависимостей.

Некоторые другие варианты: Axios, обертывание обещаний вокруг запроса или выборка… Я выбрал https.get, потому что он является частью стандартной библиотеки, и мне показалось интересным то, как он обрабатывает ответы как потоки! Что бы вы использовали?

Поскольку ответ https.get является потоком, мы объявляем body как переменную уровня блока и добавляем к ней данные, пока не получим событие end. Затем мы перезваниваем с нашими данными ответа, готовыми к использованию.

ПРИМЕЧАНИЕ. Мы даже не коснулись многих способов выполнения HTTP-запросов с помощью Javascript / Node… Проверьте это.

Резюме

По общему признанию, это был молниеносный тур, но теперь мы официально заглянули под покровы и увидели промежуточное программное обеспечение, отвечающее за общение с Yelp и получение данных, которые делают наше приложение полезным (или, по крайней мере, немного более чем бесполезным) ... мы также увидели, как быстро обходите недостатки MemoryStore по умолчанию и используйте process.env узла, чтобы легко контролировать поведение приложений и защищать конфиденциальную информацию.

Как я сказал ранее, это, вероятно, будет последняя официальная статья в этой серии ... Heroku просто сделал развертывание настолько простым, что нечего писать, их документация уже не освещена лучше, чем я когда-либо мог бы надеяться улучшить! Тем не менее, я нахожусь в процессе экспериментов с новой средой разработки, включая VSCode, ESLint и Руководство по стилю Airbnb… так что могу еще раз посетить этот проект, чтобы охватить рефакторинг.

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

Спасибо за прочтение!

PS: Если понравилось, обязательно прочтите всю серию! :-)

PPS: Изначально опубликовано здесь.