Фреймворк express - керівництво користувача
можливості
- зрозуміла маршрутизація
- Помічники перенаправлення (redirect helpers)
- Динамічні помічники уявлень
- Опції уявлень рівня додатки
- Взаємодія з контентом
- монтування додатків
- Орієнтованість на високу продуктивність
- Візуалізація шаблонів і підтримка фрагментних шаблонів (view partials)
- Конфігурації, швидко перемикаються під різні завдання (development. Production. І т.д.)
- Збережені в сесії спливаючі повідомлення (flash messages)
- Зроблено на основі Connect
- Скрипт express для швидкої генерації каркаса додатки
- Висока покриття тестами
або, щоб мати доступ до команди express, встановіть глобально:
Швидкий старт
Найпростіше почати роботу з Express можна виконавши команду express. яка згенерує додаток:
створення сервера
Щоб створити екземпляр express.HTTPServer. просто викличте метод createServer (). За допомогою нашого екземпляра додатка ми можемо задавати маршрути, засновані на HTTP-методах, в даному прикладі app.get ().
Створення HTTPS-сервера
Щоб форматувати express.HTTPSServer. ми здійснюємо ті ж дії, що і вище, але до того де передаємо об'єкт опцій, що містить ключ, сертифікат та інші параметри, про які написано в документації модуля https NodeJS.
конфігурація
Express підтримує довільні оточення (environments), як наприклад, production і development. Розробники можуть використовувати метод configure (). щоб додати потрібні для даного оточення функції. Коли configure () викликається без імені оточення, він буде спрацьовувати в будь-якому оточенні перш ніж спрацює будь configure. в якому оточення задано.
У наведеному нижче прикладі ми просто використовуємо опцію dumpExceptions і в режимі розробки видаємо клієнтові у відповідь стек-трейс виключення. В обох ж режимах ми використовуємо прошарок methodOverride і bodyParser. Зверніть увагу на використання app.router. який сам по собі дозволяє монтувати маршрути - в іншому випадку вони монтуються під час першого виклику app.get (). app.post () і т.д.
Для оточення зі схожими настройками можна передавати кілька імен оточень:
Для внутрішніх і довільних налаштувань в Express є методи set (key [, val]). enable (key). disable (key):
Щоб задати оточення ми можемо встановити змінну оточення NODE_ENV. наприклад:
Це дуже важливо, тому що безліч механізмів кешування включаються тільки в оточенні production.
З коробки Express підтримує наступні настройки:
- home - базовий шлях додатки, який використовується для res.redirect (), а також для прозорої підтримки примонтировать додатків.
- views коренева директорія уявлень. За замовчуванням текущая_папка / views
- view engine - шаблонизатор за замовчуванням для уявлень, що викликаються без розширення файлу.
- view options - об'єкт, що відображає глобальні опції уявлень
- view cache - включити кешування уявлень (включається в оточенні production)
- case sensitive routes - включити маршрути, чутливі до регістру
- strict routing - якщо включено, то завершальні Слеш більше не ігнноріруются
- jsonp callback - дозволити методу res.send () прозору підтримку JSONP
маршрутизація
Express використовує HTTP-методи для забезпечення осмисленого, виразного API маршрутизації. Наприклад, ми хочемо, щоб за запитом / user / 12 відображався профіль користувача з id = 12. Для цього ми визначаємо прівелденний нижче маршрут. Значення, пов'язані з іменованими полями, доступні в об'єкті res.params.
Маршрут це просто рядок, яка всередині движка компілюється в регулярний вираз. Наприклад, коли компілюється / user /: id. то виходить регулярний вираз на кшталт такого:
Також можна відразу передавати регулярний вираз. Але оскільки групи в регулярних виразах браком, до них можна дістатися в req.params за номерами. Так перша група потрапляє в req.params [0]. друга в req.params [1] і т.д.
Тепер візьмемо curl і надішлемо запит на вищезгаданий маршрут:
Нижче наведено кілька прикладів маршрутів і шляхи, які можуть їм відповідати:
Наприклад, ми можемо послати POST-му деякий JSON і відповісти тим же JSON-му, використовуючи прошарок bodyParser. який вміє аналізувати довільні JSON запит (як втім і інші запити) і поміщати відповідь в req.body:
Як правило ми використовуємо "дурне" поле (наприклад, / user /: id), у якого немає обмежень. Але якщо ми, наприклад, хочемо обмежити ID користувача тільки числовими символами, можна використовувати / user /: id ([0-9] +). Така конструкція не буде спрацьовувати, якщо значення поля містить нечислові символи.
Передача управління на інший маршрут
Викликавши третій аргумент - next (). можна передати управління на наступний маршрут. Якщо відповідність, не знайдено, управління передається назад в Connect, і прошарку продовжують викликатися в порядку, в якому вони були включені за допомогою use (). Так само працюють кілька маршрутів, що мають один і той же шлях. Вони просто викликаються по черзі, до того моменту, коли один з них відповість замість того, щоб викликати next ().
Метод app.all () корисний, якщо потрібно виконати одну і ту ж логіку для всіх HTTP-методів. Нижче ми використовуємо цей метод для вилучення користувача з бази даних і призначення його в req.user.
Прошарку фреймворка Connect можна передавати в express.createServer () точно так же, як якби використовувався звичайний Connect-сервер. наприклад:
Так само можна використовувати use (). Так зручніше додавати прошарку усередині блоків configure (). що більш прогресивно.
Зазвичай з прошарками Connect ми можемо підключити Connect наступним чином:
Це не зовсім зручно, тому Express повторно експортує Connect-івські прошарку:
Порядок прошарків має значення. Так, коли Connect отримує запит, виконується перша прошарок, додана через createServer () або use (). Вона викликається з трьома параметрами: request. response і callback-функція, зазвичай звана next. коли викликається next (). управління передається на другу прошарок і т.д. Це важливо враховувати, так так безліч прошарків залежать один від одного. Наприклад methodOverride () звертається до req.body.method для перевантаження HTTP-методу, а bodyParser () парсит тіло запиту, щоб заповнити req.body. Інший приклад - парсинг cookies та підтримка сесій - спочатку необхідно викликати use () для cookieParser (). потім для session ().
Безліч Express-додатків може мати рядок app.use (app.router). Це може здатися дивним, але це потрібно просто для того, щоб явно вказати прошарок, яка включає в себе всі створені нами маршрути. Цей прошарок можна включати в будь-якому порядку, хоча за замовчуванням вона включається в кінці. Змінюючи її позицію, можна управляти черговістю її виконання. Наприклад, нам потрібен обробник помилок, який буде спрацьовувати після всіх інших прошарків і відображати будь-виключення, передане в нього за допомогою next (). Або ж може знадобитися знизити черговість виконання прошарку, яка обслуговує статичні файли, щоб дозволити іншим маршрутам перехоплювати запити до таких файлів і, наприклад, рахувати кількість завантажень і т.д. Ось як це може виглядати:
Маршрути-прошарку
Маршрути можуть використовувати маршрутні прошарку шляхом передачі методу додаткових коллбеков (або масивів). Це корисно, якщо потрібно обмежити доступ або довантажувати будь-які дані перед використанням маршруту, і т.д.
Зазвичай асинхронне отримання даних може виглядати приблизно як показано нижче (тут ми беремо параметр: id і вантажимо дані юзера).
Щоб дотримуватися принципу DRY і підвищити Новомосковскбельность коду, можна організувати таку логіку за допомогою прошарків. Як можна помітити, абстрагуючись логіку за допомогою прошарків, можна як домогтися повторного використання прошарків, так і зробити код маршруту красивішим.
Беручи до уваги той факт, що прошарку - це просто функції, можна написати функцію, яка б повертала прошарок (щоб забезпечити ще більш виразне і гнучке рішення), як показано нижче.
Часто використовувані "стеки" прошарків можна передавати як масиви довільної глибини і деревовидних (вони будуть застосовуватися рекурсивно):
Повний приклад можна подивитися в репозиторії.
Бувають випадки, коли треба пропустити інші прошарки маршруту в стеці, але продовжити виконання наступних маршрутів. Для цього треба викликати next () з аргументом route. next ( "route"). Якщо не залишилося маршрутів для виконання, Express відповість помилкою 404 Not Found.
HTTP-методи
Ми вже неодноразово користувалися app.get (). проте Express також надає інші HTTP-методи - app.post (). app.del () і т.д.
Найпоширеніший приклад використання POST - це відправка форми. У прикладі нижче ми просто робимо HTML-форму. А потім управління буде передаватися маршруту, який ми визначимо в наступному прикладі.
За замовчуванням Express не знає, що йому робити з тілом запиту, тому ми повинні додати прошарок bodyParser (). яка буде парсити тіло запиту, закодоване в application / x-www-form-urlencoded або application / json. і поміщати результати парсинга в req.body. Для цього ми повинні сказати use (). як показано нижче:
Тепер нижченаведений маршрут матиме доступ до об'єкта req.body.user. у якого будуть властивості name і email:
У разі використання формою таких методів як PUT, можна використовувати прихований інпут по імені _method. який дозволяє змінити HTTP-метод. Щоб цього досягти, потрібно спочатку задіяти прошарок methodOverride (). яка буде поміщена після bodyParser (). що дозволить їй використовувати req.body. що містить поля переданої форми.
Ці прошарки не задіяні за замовчуванням, тому що Express не обов'язково повинен відразу володіти повним функціоналом. Залежно від потреб додатка, можна і не використовувати їх. І тоді методи PUT і DELETE все так же будуть доступні, але вже безпосередньо. У той же вреям methodOverride - це відмінне рішення для HTML-форм. Нижче показаний приклад використання методу PUT:
Обробка помилок
У Express є метод app.error (). який приймає всі винятки, кинуті маршрутами, або передані у вигляді next (err). Нижче приклад, як обслуговувати кілька сторінок з використанням саморобного виключення NotFound:
Можна викликати app.error () кілька разів, як показано нижче. Тут ми перевіряємо instanceof NotFound і показуємо сторінку 404. або ж передаємо управління наступному оброблювачу помилок.
Зауважте, що ці обробники можуть бути визначені де завгодно, оскільки вони все одно будуть поміщені нижче оброблювачів маршрутів в listen (). Це дозволяє їх визначати всередині блоків configure (). так що можна обробляти виключення по-різному в залежності від поточного оточення.
Для просто ти ми приймаємо тут, що всі помилки мають код 500, але ви можете це змінити як завгодно. Наприклад коли Node робить операції з файлової системою, можна отримати об'єкт помилки з полем error.code = ENOENT. що означає "не знайдений файл або директорія", ми можемо використовувати це в обробнику помилок і показувати відповідну сторінку.
Також додатки можуть використовувати для обробки винятків Connect-івську прошарок errorHander. Наприклад, якщо потрібно в оточенні development показувати виключення в stderr. можна зробити так:
Також в ході розробки нам можуть знадобитися кльові HTML-сторінки, що показують передані або кинуті виключення. У такому випадку потрібно встановити showStack в true:
Прошарок errorHandler також відповідає в JSON, якщо клієнтом переданий заголовок Accept: application / json. що корисно для розробки AJAX-додатків.
Пред-обробки параметрів маршруту
Пред-обробки параметрів маршруту можуть істотно поліпшити Новомосковскбельность додатки, через явну завантаження даних і валідацію URL запиту. Наприклад, якщо ви постійно отримуєте якісь дані для певних запитів (наприклад вантажите призначені для користувача дані для / user /: id), можна зробити щось на зразок цього:
З пред-умовами на наші параметри запиту можна навісити callback-функції, які б виконували валідацію, обмеження доступу, або навіть завантаження даних з бази даних. У прикладі нижче ми викликаємо app.param () з ім'ям параметра, на який хочемо навісити callback. Як можна помітити ми отримуємо аргумент id. який містить ім'я поля. Таким чином ми завантажуємо об'єкт користувача та виконуємо звичайну обробку помилок і простий виклик next (). щоб передати управління на наступне перед- умова або вже на обробник маршруту.
Вищевказані дії, як уже говорилося, значно покращують Новомосковскбельность коду і дозволяють легко використовувати одну логіку в різних місцях програми:
Візуалізація уявлень
Імена файлів уявлень утворюються за схемою <имя>. <движок>. де <движок> - це назва модуля шаблонізатора, який повинен бути підключений. Наприклад уявлення layout.ejs говорить системі уявлень, що треба зробити require ( 'ejs'). Щоб інтегруватися в Express, що завантажується модуль повинен експортувати метод exports.compile (str, options). і повертати функцію. Щоб змінити цю поведінку, можна користуватися методом app.register () - він дозволяє проасоціювати розширення файлів з певними двигунами. Наприклад можна зробити, щоб foo.html Рендер движком ejs.
Нижче - приклад, який використовує Jade для рендеринга index.html. І оскільки ми не використовуємо layout: false. відрендерене контент уявлення index.jade буде переданий як локальна змінна body в уявлення layout.jade.
Налаштування view engine дозволяє вказати шаблонизатор за замовчуванням. Так наприклад при використанні Jade можна зробити так:
що дозволить нам рендерить так: