Node.js Recipes
3.23K subscribers
175 photos
7 videos
1 file
622 links
По буднях нотатки по #Nodejs розробці, по вихідним огляди конференцій та доповідей (с) @galkin_nikita
Download Telegram
​​Сравнение Nest.js и Koa.js с точки зрения бизнеса
#nestjs

Эта заметка развернутый ответ на вопрос: "можешь подсказать основные плюсы nestJS vs koaJS?". Между строк у автора вопроса читается желание продать использование Nest.js на проекте. 

Любая продажа происходит через вопросы. Продающие вопросы для PM/PO/заказчика/бизнеса в данном случае:
- На сколько сложная бизнес логика на бэкенде?
- Есть ли время писать документацию?
- Планируется ли расширение команды?

Пример использования вопросов.

Koa.js – это библиотека для написания REST API, в то время как Nest.js – фреймворк. В тривиальных случаях использование фреймворка не оправдано. Поэтому лендинги делают на jQuery, т.е. с использование библиотеки, а не на React/Angular/Vue. На сколько сложная бизнес логика на бэкенде? Можно ли ее считать настолько простой, что не нужен фреймворк, а достаточно библиотеки?

Фреймворк это не только набор библиотек, но и методология/философия разработки. Не используя готовый фреймворк, команда не явно создает свой собственный. Есть ли время писать документацию? Документацию по тому, как используются библиотеки, как ведется разработка? А спецификацию на REST API, которую Nest.js умеет генерировать, а Koa.js – нет?

Без документации onboarding нового разработчика будет дольше. Планируется ли расширение команды? В 2021 общепринятый технический стэк #nodejs проекта базируется на Nest.js с применением TypeScript и TypeORM. Конечно, можно построить (продолжать использовать) фреймворк на базе Koa.js. Каковы риски, что это будет причиной ухода разработчиков? А отказа в принятие оффера хорошим кандидатом?

Обратите внимание, продающие вопросы не об технологиях. Для бизнеса технологии вторичны. Хорошие разработчики выбирают фреймворки и библиотеки под задачи, поэтому вопроса "Кoa.js или Nest.js" быть не может. Необходимо владеть обоими инструментами.
Как конфигурировать Node.js приложение?
#best_practice #package #devops

TL;DR Конфигурация хранится в переменных окружения без значений по умолчанию. Если какой-либо переменной нет или формат не верный, то приложение не должно запускаться. Требуемые переменные описываются в env.example. Реализация dotenv-safe

Теория
Каждому #nodejs разработчику следует знать 12 факторный манифест . Следование его принципам позволит создавать масштабируемые веб-приложения и комфортно сотрудничать с DevOps инженерами. Третий фактор говорит, что конфигурация должна храниться в настройках окружения (env vars). Рекомендую с этим фактором ознакомиться, там подробно описано почему стоит использовать именной такой подход.

Применение
Значения всех переменных окружения доступны:
- в терминале с помощью команды env
- на уровне Node.js кода с помощью объекта process.env.

Значения конкретной переменной <NAME> доступно:
- в терминале с помощью $<NAME>
- на уровне Node.js кода с помощью process.env.<NAME>

Установить переменные окружения можно:
– посредством команды export. Например: export NODE_ENV=production . Результат команды не сохраняется между сессиями консоли. Для внесения долгосрочный изменений в окружение команду необходимо прописать в .bashrc или его аналог.
– посредством команды source
– В момент запуска процесса как ИМЯ=ЗНАЧЕНИЕ перед самой командой. Пример: NODE_ENV=production DEBUG=0 node src/index.js Работает как в терминале, так и в npm scripts.
– Изменением значений в process.env уже во время работы приложения.
 
.env
.env файл с переменными окружения используется для упрощения локальной разработки. На всех других окружениях его использование является плохой практиков. .env никогда не должен храниться в git репозитории. Поддержка есть во всех IDEA. Для консоли есть расширения, например autoenv. На уровне кода общепринятым пакетом является dotenv. Он вычитывает в process.env значения из .env, но не заменяет уже существующие значения.

.env.example
.env.example описывает все требуемые переменные окружения для работы приложения. Там можно и нужно делать комментарии. Это single source of truth для вашего DevOps инженера. Его необходимо хранить в git. Если приложение, не имеет какого-либо из ожидаемых переменных, то оно не должно стартовать. Fail fast! Этот функционал обеспечивает пакет dotenv-safe, который является оберткой над dotenv.

Советы по уменьшению количества переменных
– Используйте connection string. Пример: DB_URL=postgresql://postgres:password@localhost:5432/database
Используйте JSON в значениях переменных. Пример: const stripeConfig = JSON.parse(process.env.STRIPE_CONFIG)
Используйте значения через запятую. Пример: const adminList = process.env.ADMINS.split(',')

Распространенные ошибки
– Отсутствие приведение типа. Все ключи объекта process.env имеют значения типа string. Пример, вопреки ожиданиям при запуск с SOME_FEATURE=false код if process.env.SOME_FEATURE ... будет исполнен.
– Использование значений по умолчанию. Пример, const logLevel = process.env.LOG_LEVEL || 'info'. Это приводит к неявной конфигурации и дорогостоящим ошибкам.
– Ошибка в путях к .env из-за использования относительных, а не абсолютных путей.
– Ошибка характерная для FE разработчиков: не понимание разницы между переменными окружения в build-а и run time.
– Ошибка характерная для microservice разработчиков в проектах с Service discovery: различие локального и прод окружений. Необходимо запускать Consul или его аналоги через Docker.
StrapiConf
#conference #freebies

В начале года на #nodejs проекте нужно было прикрутить CMS (систему управления контентом). Я остановился на Strapi. Открытый исходный код на Node.js, активное комьюнити, хорошая документация, koa под капотом: определили мой выбор. А еще стабильный вендор, который в мае 2020 закрыл А раунд в 10 млн долларов инвестиций.

Вот сегодня у нас обзор StrapiConf. Это vendor-конференция. Такие конференции проводятся вендором, чтобы популяризировать использование своих продуктов. Обратите внимание не прорекламировать, а популяризировать, то есть объяснить зачем создано решение и как его использовать. Среди докладчиков как внутренние сотрудники компании, так представители партнеров и комьюнити.

Детали:
1. Онлайн.
2. Дата проведения 22 апреля 2021, в следующий четверг.
3. Бесплатная регистрация. Кстати, такие вещи в канале идут под тегом #freebies.
4. Три потока докладов и один поток воркшопов.
5. Плюшки от парнеров. Часть из них доступна без регистрации. Мне был полезен промкод для Sentry.

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

Если вы не работали со Strapi, то рекомендую Strapi 101 - The Fundamentals. Для продвинутых будет полезен Moving Content Between Multiple Strapi Environments.
1
GraphQL Summit Worldwide - April 2021
#worth_seeing #graphql

На эти выходные мой плейлист это видео c GraphQL Summit Worldwide. Это vendor-конференция от Apollo GraphQL, который является де-факто стандартом для GraphQL проектов. Весь плейлист занимает 3.5 час и делает обзор новинок в GraphQL экосистеме.
1
Can we double HTTP client throughput?
#worth_seeing

Сегодня у нас обзор доклада Matteo Collina, автора fastify и активного контрибьютора в #nodejs. Он объясняет как увеличить пропускную способность http клиента. Лучшее применение идей доклада будет в микросервисной архитектуре с внутренней коммуникацией по REST. Так же их полезно использовать при большом количестве запросов к внешним сервисам.

Увеличение пропускной способности обеспечивается за счет использования keepAliveAgent и connection pool (прям как в базах данных). Реализацией этих идей является пакет от Matteo undici.
Как узнать ip пользователя в Node.js?
#package #nestjs

TL;DR Знайте заголовок, который использует ваш LB или используйте request-ip.

Хорошей практикой является логирование ip адрес, с которого идет запрос. В определенных случаях в зависимости от ip может строиться логика работы приложения. Наивный способ, приведенный в #nodejs документации выглядит так:

const http = require('http');
const server = http.createServer((req, res) => {
const ip = res.socket.remoteAddress;
const port = res.socket.remotePort;
res.end(`Your IP address is ${ip} and your source port is ${port}.`);
}).listen(3000);

В реально проекте данный способ не будет работать. Node.js процесс будет находиться за load balancer-ом. В req.socket.remoteAddress будет находиться именно его ip, а не откуда пришел запрос. Оригинальный ip можно узнать по заголовку X-Forwarded-For или его аналогам (зависит от используемого LB).

Если у вас нет информации, как будет развернут ваш код, то стоит использовать пакет request-ip. В его коде идет перебор большинства заголовков в поисках ip.

Если же вы знаете используемый LB, то знаете имя заголовка. Вот пример для #nestjs декоратора:

import { createParamDecorator, ExecutionContext } from '@nestjs/common';
import { Request } from 'express';

export const UserIp = createParamDecorator((data: unknown, context: ExecutionContext) => {
const req = context.switchToHttp().getRequest<Request>();
const forwardedFor = req.header('x-forwarded-for');
if (!forwardedFor) return req.connection.remoteAddress;

return forwardedFor.split(',')[0];
});
​​Как получить бесплатную Node.js сертификацию?
#freebies

На прошлой неделе был на подкаст, где среди прочего мы с Ильей Климовым обсуждали сертификацию для #nodejs разработчиков от Linux Foundation. Их существует две:
- JSNSD – OpenJS Node.js Services Developer
- JSNAD – OpenJS Node.js Application Developer

Как и другие сертификации от LF они стоят по 300$. На них регулярно бывают скидки, поэтому покупать их дороже 150$ не рационально... На этом я остановлюсь, иначе это будет пересказ подкаста.

Linux Foundation регулярно раздает купоны на 100% скидку и называет это Linux Foundation Training Scholarships. Для участия достаточно заполнить форму. В случае если вам повезет, то вы получите два промокода: один на сертификацию, второй на платный курс.

В прошлом году я уже участвовал в этой программе и получил CKAD – Certified Kubernetes Application Developer. Распределение по категориям и стипендиатов 2020 можно посмотреть тут. Надеюсь увидеть вас в списке 2021.
Как в Node.js узнать местоположение пользователя?
#service #gcp

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

Начинающие #nodejs разработчики устанавливают geoip-lite. В результате приложение потребляет на 100мб памяти больше. Под капотом у пакета GeoLite база от MaxMind, которая будет находиться в памяти.

Продвинутые разработчики используют сторонний сервис. Например, db-ip.com или geoip2. К сожалению, такие решения нельзя назвать дешевыми.

Наиболее опытные разработчики оптимизируют затраты, и поэтому решают эту задачу в Google Cloud Platform. Один из таких разработчиков написал статью Free IP-based GeoLocation with Google Cloud Functions. В ней описано как создать функционал аналогичный db-ip.com.

В Google Cloud Platform можно настроить custom headers так, что запрос в Node.js будет иметь заголовки с нужными данными.

Аналогичный функционал дает geoip2 модуль для nginx, но он доступен только в nginx-plus.
​​Какую версию npm использовать?
#best_practice #npm #tech_stack

Node package manager – npm регулярно показывает Update available. Следовать этому оповещению и обновлять npm не стоит. Вместе с версией #nodejs идет конкретная версия npm и именно ее следует использовать. Версии указаны в таблице.

Пример текущей LTS комбинации: Node.js v14.16.1, npm v6.14.12. Этому следуют все:
- установочные бинарники,
- nvm (node version manager) и его аналоги,
- Docker image

Использование различных версий npm ведет к различному поведению приложения, трудноуловимым багам и git конфликтам.

Если вы используете yarn, то такой таблицы нет. Лучшей практикой будет использование версию прошитой в Docker image. Например, для Node.js v14.16.1 это будет yarn v1.22.5
​​Free GitLab Certified Associate
#freebies

За последние 12 месяцев GitLab запустил 6 сертификаций различного уровня. GitLab Certified Associate это начальный уровень. Если у вас в резюме нет ни одного бейджа, то рекомендую начать с этого.

Цена без промокода $650. До 30 Апреля 2021 работает E6B8A234458AE3D795. Активация:
1. Создать аккаунт на https://gitlab.edcast.com/
2. Добавить GitLab Certified Associate Pathway в корзину
3. При оплате использовать промокод.

Источник.
​​Как правильно написать package.json в проекте?
#package #best_practices

#Nodejs проект начинается с package.json. Давайте посмотрим как правильно его составить для коммерческого кода.

"name": "@<scope>/<name>"
Хорошая практика использовать scoped package.
"version": "0.1.0"
SemVer рекомендует начинать именно с 0.1.0
"private": true,
Чтобы случайно не опубликовать.
"license":""UNLICENSED"
Поле license описывает тип Open Source лицензии.
Поля "description" и "keywords" используют для поиска в публичном npm. Не указываем их.
"author": "Company Name",
Имя компании обладающей правом на код
"scripts": { использует одинаковое именование. Единого подхода нет. Подробней
"dependencies": { содержит те пакеты, которые используются в runtime, для FE – во время сборки.
"devDependencies": { содержит пакеты, которые необходимы для локальной разработки и CI/CD.

Все зависимости не меняются руками. Только в посредством npm install/uninstall, чтобы изменился package-lock.json.

Организовать порядок в файле помогает sort-package-json. Ставить его нет смысла, поэтому npx sort-package-json.
👍1
Кодстайл и насилие, Антон Немцев
#worth_seeing

Разработчик читает в десятки раз больше строчек кода, чем пишет. Поэтому кодстайл так важен. Доклад Антона снят в 2018 год. За это время часть инструментов поменялось, но принципы высказанные в докладе актуальны и сейчас.
📕 Slides
Конференции, которые нужно знать:
– Google: I/O '21 18-20 мая, Cloud Next'21 12-14 октября
– Microsoft: Build 25-27 мая
– Facebook: F8 Refresh 2 июня
– Apple: WWDC21 7-11 июня
– AWS: re:Invent 29 ноября - 3 декабря
#conference
На них говорят о вещах, которые меняют нашу отрасль.
6 способов взломать твое JavaScript приложение. Виктор Турский
#worth_seeing #security

В докладе:
- Использование SMS для восстановления пароля
- Загрузка аватарки в файловую систему, а не S3
- Раздача статики средствами #nodejs
- Использование MongoDB
- Server Rendering
- XSS

Во всех примерах, безопасный на первый взгляд код превращается в серьезную проблему в безопасности.
Cloud Study Jam 29-04-2021
#announcement

Мое основное облако – Google Cloud Platform. Если вы с ним не работали, то я вас приглашаю в этот четверг на Cloud Study Jam. В его ходе вы получите свой первый бейдж на qwiklabs.com.
Так же мы посмотрим как сделать свой определитель адреса по IP, о котором я рассказывал тут.
Node.js Recipes pinned «Cloud Study Jam 29-04-2021 #announcement Мое основное облако – Google Cloud Platform. Если вы с ним не работали, то я вас приглашаю в этот четверг на Cloud Study Jam. В его ходе вы получите свой первый бейдж на qwiklabs.com. Так же мы посмотрим как сделать…»
Как узнать источник соединение в БД?
#best_practice #database

TL;DR Всегда ставьте application_name в конфигурации подключения к БД.

Сегодня обсудим малодокументированную фишку баз данных. При создание соединения можно указать application_name. Это аналог http заголовка User-Agent в мире баз данных. Он виден в списке соединений и slow query log. Приведу примеры кода для PostgreSQL.

Без ORM:
import { Client } from 'pg';
const client = new Client({
connectionString: process.env.DB_URL,
application_name: 'my-app@0.1.0'
});

TypeORM
import { PostgresConnectionOptions } from 'typeorm/driver/postgres/PostgresConnectionOptions';
const dbConfig: PostgresConnectionOptions = {
type: 'postgres',
url: process.env.DB_URL!,
extra: { application_name: 'my-app@0.1.0' },
entities: ...
};

Sequelize
import { Sequelize } from 'sequelize';
const sequelize = new Sequelize(process.env.DB_URL!, {
dialect: 'postgres',
dialectOptions: { appName: 'my-app@0.1.0' }
});


Теперь вы сможете увидеть application_name в pg_stat_activity с помощью запроса
SELECT * FROM pg_stat_activity WHERE datname = '<db_name>';

Аналогичные параметр есть у всех клиентов баз данных.
Например, MongoDB использует appName, а Redis – CLIENT SETNAME.
​​Как вывести в браузер сколько времени обрабатывался запрос на сервере?
#package #browser

Сегодня посмотрим, как можно узнать:
- Как быстро браузер получил ответ?
- А сколько запрос обрабатывался на сервере?

Chrome показывает Server-Timing заголовки. Для этого:
1️⃣Открываем исследуемый ресурс и консоль разработчика.
2️⃣Переходим во вкладку Network.
3️⃣Выбираем нужный запрос.
4️⃣Переходим во вкладку Timing.
5️⃣Смотрим результат.

Есть уже готовый пакет server-timing. Меня он сильно выручил в ситуации, когда было не ясно тормозит #nodejs или load-balancer.
​​Бесплатная месячная подписка на O'Reilly
#freebies

Спасибо, что читаете мой канал об #nodejs. Я стараюсь сделать рецепты короткими, но полезными. Они такие, чтобы читать их на бегу.

К сожалению, книги так не почитаешь. А читать книги необходимо! Лучшие книги по разработке издает издательство O'Reilly (такие с животными на обложке). У них есть замечательный портал learning.oreilly.com. Помимо книг там есть видео и тренировочные сертификации. Отличный контент, который я люблю читать с планшета.

Одна беда – цена 50$/месяц, 500$/год.

У них есть trial 10 дней, но этого мало, чтобы прочитать книгу. По ссылке https://learning.oreilly.com/get-learning/ можно получить 30 дней. Промокод прикреплен снизу.

Приятного чтения!
​​Как померять время выполнения команды в терминале?
#cli

TL;DR Используйте hyperfine

Стандартный способ померять время исполнения команды посредством time.
Пример: time npm run build.

Если time использовать в связке с curl, то можно узнать время выполнения запроса. Для такой задаче лучше подходит ab. Это сокращение от apache benchmark. Это команда отправляет не один запрос на указанный URL, а несколько. На основание результатов считаются статистики: средние, квартили и тп. Поэтому в название и есть benchmark.
Пример: ab -n 10 http://localhost:3000/

Для оценки cli команд тоже есть benchmark. Называется hyperfine. Он может сравнивать несколько команд, делать прогрев или подготовку.
Пример: hyperfine 'npm run build'.
Его удобно использовать в извечном холиваре #nodejs разработчиков: yarn vs npm. Вот так можно сделать сравнение для вашего проекта:
hyperfine --prepare 'rm -rf node_modules' 'yarn' 'npm install'