Как улучшить ваш API сервис на node.js. Часть 1

от автора

Сейчас доступно приличное количество материалов по написанию API на node.js. Большинство из них в виде туториалов и демо-примеров в документациях. Этого достаточно, чтобы быстро разобраться и написать что-то свое. Но в них редко найдутся детали, почему это делается именно так. А некоторые моменты и вовсе опускаются для простоты и краткости.

Это статья нацелена, чтобы заполнить некоторые пробелы, которые могли возникнуть, и в конечном счете улучшить вам сервис на node.js.

P.S. Ни в коем случае не считаю себя экспертом: есть куда расти. Но вместе с тем есть чем поделиться.

Файловая структура проекта

Файловая структура — базовая, но очень важная вещь. При ее создании стоит предусмотреть возможность масштабирования сервиса, именно по этой причине не стоит размещать файлы в плоской структуре одного каталога. Нужна иерархия, нужна модульность.

При наименовании каталогов необходимо придерживаться устоявшихся стандартов. Это поможет коллегам и самому через пару месяцев быстро сориентироваться где и что находится.

Пример файловой структуры

src/     controllers/          users/              index.js          index.js     db/          mongo/              index.js          index.js     helpers/     middlewares/          auth.js     models/          users.js     routes/         users/              index.js         index.js     index.js  .eslintrc .gitignore README.md ... package.json 

Примечания:

  1. Все исполняемые файлы должны располагаться в ./src
    Это позволит отделить исходные файлы от скомпилированных typescript`ом или babel`ем, которые будут располагаться в ./dist или ./build.
    Также это позволит легче настроить линтеры и прочие конфигурируемые инструменты, так как целевые файлы располагаются в отдельном каталоге.
  2. Все сущности контроллеров и роутов размещайте в отдельных каталогах
    Это позволит открыв ./routes или ./controller, увидеть лишь один index.js файл, импортирующий и экспортирующий сущности подкаталогов.
    Это позволит быстрее сориентироваться в имеющемся функционале, так как он описывает лишь интерфейс контроллеров или роутеров без вникания в их реализацию.

О компиляции Javascript

Конечно, вы можете не использовать babel или typescript для преобразования вашего javascript`а. Как правило, новые стандарты ECMAScript`а быстро оказываются в node.js, да и вы, в исключение от браузерного javascript’a, способны контролировать их поддержку.
Но я убежден, что их стоит использовать. И вот почему:

  1. Не всегда последняя версия Node.js доступна для продакшена.
  2. У Node.js (v. 13) до сих пор есть проблемы с поддержкой ECMAScript модулей, хоть они и появились и ушли из-под флага, но до сих пор являются экспериментальными. Для прода рано.

Рассмотрим добавление babel`я в проект:

Установим зависимости:

npm install @babel/core @babel/node @babel/preset-env --save-dev 

Добавим конфигурационный файл .babelrc в корень проекта

{     "presets": [       "@babel/preset-env"     ] } 

Пример запуска скрипта

"start": "nodemon --exec babel-node src/index.js", 

Примечания:

  1. Не забывайте при установки зависимостей, необходимых только на этапе разработки проставлять ключ —save-dev (-D). Это необходимо как минимум для семантики.

О необходимости линтеров

Начнем с очевидного факта: линтеры нужны. Мы пишем код, много кода. Так много что, сами не способны контролировать его единообразие. Этот пункт неимоверно усиливается при командной разработке.

А единообразие — залог читаемости кода.

Остается вопрос о строгости линтера. Выбор которой должен основывается на размерах команды, их профессиональном уровне, важным критерием выступает сам проект.

Добавление простого линтера в проект

Установим зависимости:

npm install eslint --save-dev 

Добавим конфигурационный файл .eslintrc в корень проекта:

{     "env": {         "node": true,         "es6": true,     },     "extends": "eslint:recommended" } 

Как правило, такого конфига не достаточно. Тут либо самому расширять правила или присмотреться на заготовленные более строгие варианты.

Пример добавление, новых правил ...     "extends": "eslint:recommended",     "rules": {         "quotes": ["error", "single"]     } } 

Использование более строгого линтера

Сейчас есть несколько популярных конфигураций на основе одноименных стайл-гайдов.

  • Google
     npm install --save-dev eslint-config-google 
  • Airbnb
     npm install --save-dev eslint-config-airbnb-base eslint-plugin-import 
  • Idiomatic
     npm install --save-dev eslint-config-idiomatic 

Соответственно, необходимо будет подправить .eslintrc

{     "env": {         "node": true,         "es6": true,     },     "extends": "google" | "airbnb-base" | "idiomatic" } 

Также необходимо добавить запуск линтера в отдельный скрипт.

"lint": "eslint ./src --cache && echo \"eslint: no lint errors\"", "lint:fix": "eslint ./src --fix && echo \"eslint: no lint errors\"" 

О запуске приложения

Любой, кто имеет доступ к репозиторию проекта, должен суметь запустить его. Сможет ли он это сделать и сколько ему для этого понадобиться времени — это один из ваших критериев качества проекта.

Важно заранее продокументировать как пошагово запустить сервис в README.md файле, а также прописать команды для основных действий.

"start": "npm run dev", "dev": "nodemon --exec babel-node ./src/index.js", "build": "babel ./src --out-dir ./build", "prod": "NODE_ENV=production node ./build/index.js", "lint": "eslint ./src --cache && echo \"eslint: no lint errors\"", 

Чтобы использовать вышеприведенные команды, вам возможно понадобиться установить следующие пакеты:

npm install --save-dev @babel/cli nodemon babel-node 

Примечание:

  1. Если вы даже добавили основные команды в package.json, все равно опишите в README.md процесс запуска.

Заключение

Первоначально в статье хотелось осветить гораздо больше рекомендаций по написанию API на node.js, но хочется укладываться в 3-5 мин. прочтении статьи. При условии хорошей обратной связи выйдет продолжение.

ссылка на оригинал статьи https://habr.com/ru/post/489584/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *