Як написати проміжне програмне забезпечення

Чи замислюєтесь ви коли-небудь про те, що відбувається в усіх проміжних програмах Express.js, які ви додаєте у свій веб-додаток? Насправді дуже вражає, яку функціональність ви можете додати до своїх програм лише одним рядком коду або кількома:

проміжне

Останні три рядки зверху обробляють для нас досить багато функцій веб-додатків. Перший виклик app.use () повідомляє Express, де знаходяться наші статичні файли та як їх виставити, проміжне програмне забезпечення cookieParser ('sekret') обробляє весь аналіз файлів cookie (з шифруванням), а останній автоматично gzip стискає всі наші HTTP дані тіла. Непогано лише для трьох рядків коду.

Це проміжне програмне забезпечення є досить типовим у вашому середньому веб-додатку, але ви можете знайти деякі з них, які роблять більше, ніж просто стандартне стиснення даних або синтаксичний аналіз файлів cookie. Візьмемо такі приклади:

  • шолом: допомагає захистити ваш додаток, встановлюючи різні заголовки HTTP
  • express-simple-cdn: Легко використовуйте CDN для своїх статичних активів
  • join-io: об’єднуйте файли на льоту, щоб зменшити кількість запитів HTTP
  • паспорт: додає аутентифікацію користувача до вибраних маршрутів

І ось набагато більший перелік проміжних програм, якими ви можете скористатися.

Тепер, коли ви побачили кілька прикладів, ось майже все, що ви можете з цим зробити:

  • Виконайте будь-який код, включаючи асинхронний код
  • Вносити зміни або доповнення до об’єктів запиту та відповіді
  • Завершіть цикл запит-відповідь
  • Викличте наступне проміжне програмне забезпечення в стеку

З нескінченними можливостями, я впевнений, у вас є власні ідеї, які ви хотіли б створити, тому протягом решти цієї статті я покажу вам, як написати власне проміжне програмне забезпечення. Існує кілька різних типів проміжного програмного забезпечення, яке ви можете писати (програма, маршрутизатор, обробка помилок тощо), але в цій статті ми зосередимося лише на рівні програми.

Основи

Проміжне програмне забезпечення можна сприймати майже так, ніби це експрес-маршрут. Вони приймають однакові параметри і все, але на відміну від звичайних маршрутів вам не потрібно вказувати URL-адресу для проміжного програмного забезпечення. Дві найбільші відмінності полягають у тому, як трактується шлях і коли його викликають.

Наданий шлях розглядається як префікс, тому якщо у вас було щось на зразок app.use ('/ api',.), Тоді ваше проміжне програмне забезпечення буде працювати, якщо буде викликано/api і якщо буде викликано/api/users. Це відрізняється від маршрутів, де шлях повинен точно відповідати.

Шлях URL-адреси може бути опущений із виклику app.use (), якщо ви хочете, щоб ваш код запускався для всіх запитів, інакше ви можете вказати шлях, і ваш код повинен працювати лише тоді, коли цей маршрут (і всі його під-маршрути) на запит. Наприклад, це може бути корисно для додавання автентифікації лише до кількох заданих маршрутів.

Просте проміжне програмне забезпечення може виглядати так:

Тоді як обробник маршруту виглядає так:

Побачити? В основному це одне і те ж, тому написання цих функцій вам повинно здаватися досить знайомим.

Використовуються такі параметри:

  • req: Об'єкт, що містить всю відповідну інформацію про запит. Це може бути будь-що - від URL-адреси, що запитується до тіла запиту POST, до IP-адреси користувача.
  • res: Це об'єкт відповіді, який використовується для надсилання даних користувачеві для даного запиту. Ви можете використовувати це, щоб надіслати назад код відповіді HTTP 404 або повернути відтворений HTML через res.render () .
  • наступний: І нарешті, наступним параметром є зворотний виклик, щоб повідомити Express, коли наше проміжне програмне забезпечення закінчиться. Якщо ви виконуєте будь-який IO (наприклад, дзвінки до бази даних) або важкі обчислення, вам, ймовірно, доведеться зробити функцію асинхронною, щоб запобігти блокуванню основного потоку виконання, і в цьому випадку вам доведеться використовувати наступний .

Варто зазначити, що якщо ваше проміжне програмне забезпечення не закінчує цикл запиту-відповіді за допомогою res.end (.), То ви повинен зателефонуйте next (), щоб передати управління наступному проміжному програмному забезпеченню. Якщо ви цього не зробите, запит залишатиметься вимкненим і очікує очікування.

Приклад

У цьому прикладі ми створимо проміжне програмне забезпечення, яке допоможе вам автоматично перекладати текст між мовами. Однак це не типовий модуль i18n, замість цього ми будемо використовувати Google Translate.

Скажімо, ви створили додаток для чату, який дозволяє розмовляти з людьми по всьому світу, і щоб зробити його безшовним, вам потрібно автоматично перекласти текст. У цьому варіанті використання більшість модулів i18n не працюватимуть, оскільки вам потрібно попередньо перекласти всі рядки, чого ми не можемо зробити, оскільки ми маємо справу з введенням користувача.

Звичайно, ви могли б обробляти переклад на кожному з ваших експрес-маршрутів, або ви могли б його обробити для вас у проміжному програмному забезпеченні, яке підтримує ваш код маршруту чистішим і не дозволяє вам забути додати переклад до кожного маршруту, який потребує цього.

Рядки (повідомлення користувачів) надходять через REST API, тому нам потрібно буде перевірити всі тіла маршрутів API на наявність тексту для перекладу. Усі рядки, що зберігаються в базі даних у викликах POST, зберігатимуться на їх рідних мовах, але всі рядки, що отримуються з бази даних за допомогою викликів GET, будуть перекладені на мову, зазначену в заголовку HTTP Accept-Language, що супроводжує запит користувача.

Я припустив, що ми не зробимо всі повідомлення в базі даних однією мовою, оскільки тоді нам доведеться перекласти деякі з них двічі, що погіршує якість перекладу.

Спочатку напишемо просту функцію для виклику Google Translate API:

Тоді ми будемо використовувати цю функцію в коді проміжного програмного забезпечення, який експортується в модулі.export для використання додатком.

ПРИМІТКА: Це насправді не те, як ви змінюєте тіло відповіді. Я просто спрощую це заради стислості. Якщо ви хочете побачити, як насправді змінити тіло, перевірте проміжне програмне забезпечення для стиснення, яке робить це належним чином. Ви повинні проксі-функції res.write та res.end, чого я не робив, оскільки це просто відволікало б увагу від концепцій, які я намагаюся показати тут.

І нарешті, ми застосовуємо проміжне програмне забезпечення до нашого додатку. Просто переконайтеся, що ви викликали функцію app.use після того, як ви вже заявили про свої маршрути. Порядок його виклику - це порядок роботи кожної функції.

Крім того, переконайтеся, що ви телефонуєте next () у кожному з ваших маршрутів/api, інакше проміжне програмне забезпечення не запуститься.

І це все. Будь-який рядок, що повертається в тілі відповіді, що відрізняється від мови, прийнятої користувачем, буде перекладений Google Translate, який визначає, якою мовою є вихідний текст.

Отже, якщо наша відповідь почалася виглядати так.

. і користувач приймає лише суахілі, тоді після запуску проміжного програмного забезпечення ми отримаємо остаточний переклад, який виглядає так:

Висновок

Хоча це може здатися залякуючим, проміжне програмне забезпечення дуже просто створити в Express. Ви можете використовувати його майже для будь-чого, незалежно від того, наскільки це просто або складно.

Тільки обов’язково виконайте швидкий пошук у npm для того, що ви намагаєтесь зробити, оскільки тонни коду вже є. Я впевнений, що вже існує пакет, який робить те, що робить мій код перекладу (і, можливо, набагато краще).

Чи є у вас ідеї щодо створення проміжного програмного забезпечення або як покращити мій приклад вище? Повідомте нас у коментарях!