Перевод книги Node Hero от RisingStack. Переведено с разрешения правообладателей.
В этой главе я расскажу вам о том, как вы можете запустить простой HTTP-сервер на Node.js и начать обрабатывать запросы.
Когда вы начинаете создавать HTTP-приложения в Node.js, встроенные модули http/https
- это то, с чем вы будете взаимодействовать.
Давайте создадим ваш первый HTTP-сервер на Node.js! Нам будет нужно подключить модуль http
и привязать наш сервер к порту 3000
.
// содежимое index.js
const http = require('http')
const port = 3000
const requestHandler = (request, response) => {
console.log(request.url)
response.end('Hello Node.js Server!')
}
const server = http.createServer(requestHandler)
server.listen(port, (err) => {
if (err) {
return console.log('something bad happened', err)
}
console.log(`server is listening on ${port}`)
})
Затем запускаем этот скрипт:
$ node index.js
Что нужно здесь отметить:
requestHandler
: эта функция будет вызываться каждый раз, когда на сервер придёт запрос. Если вы откроете в своём браузере адресlocalhost:3000
, два сообщения появятся в консоли: одно для/
и одно дляfavicon.ico
.if (err)
: обработка ошибок: если порт уже занят или есть какие-то другие причины, по которым сервер не может быть запущен, мы получим уведомление об этом.
Модуль http
крайне низкоуровневый: создание сложного веб-приложения с использованием вышеприведенного фрагмента кода очень трудоемко. Именно по этой причине мы обычно выбираем фреймворки для работы над нашими проектами. Есть множество фреймворков, вот самые популярные:
В этой и следующих главах мы будем использовать Express, так как именно для него вы можете найти множество модулей в NPM.
Быстрый, гибкий, минималистичный веб-фреймворк для Node.js — http://expressjs.com/
Добавление Express в ваш проект - это просто установка через NPM:
$ npm install express --save
После того, как вы установили Express, давайте посмотрим, как создать приложение аналогичное тому, что мы написали ранее:
const express = require('express')
const app = express()
const port = 3000
app.get('/', (request, response) => {
response.send('Hello from Express!')
})
app.listen(port, (err) => {
if (err) {
return console.log('something bad happened', err)
}
console.log(`server is listening on ${port}`)
})
Самое большое различие, которое вы можете здесь заметить, заключается в том, что Express по умолчанию даёт вам роутер. Вам не нужно вручную разбирать URL, чтобы решить, что делать, вместо этого вы определяете маршрутизацию приложения с помощью app.get
, app.post
, app.put
и так далее, а они уже транслируются в соответствующие HTTP-запросы.
Одна из самых мощных концепций, которую реализует Express — это паттерн Middleware.
Вы можете думать о промежуточных обработчиках как о конвейерах Unix, но для HTTP-запросов.
На диаграмме вы можете увидеть, как запрос идёт через условное Express-приложение. Он проходит через три промежуточных обработчика. Каждый обработчик может изменить этот запрос, а затем, основываясь на вашей бизнес-логике, третий middleware отправит ответ, либо запрос попадёт в обработчик соответствующего роута.
На практике вы можете сделать это следующим образом:
const express = require('express')
const app = express()
app.use((request, response, next) => {
console.log(request.headers)
next()
})
app.use((request, response, next) => {
request.chance = Math.random()
next()
})
app.get('/', (request, response) => {
response.json({
chance: request.chance
})
})
app.listen(3000)
Что следует здесь отметить:
app.use
: это то, как вы можете описать middleware. Этот метод принимает функцию с тремя параметрами, первый из которых является запросом, второй — ответом, а третий — коллбекомnext
. Вызовnext
сигнализирует Express о том, что он может переходить к следующему промежуточному обработчику.- Первый промежуточный обработчик только логирует заголовки и мгновенно вызывает следующий.
- Второй добавляет дополнительное свойство к запросу - это одна из самых мощных функций шаблона middleware. Ваши промежуточные обработчики могут добавлять дополнительные данные к объекту запроса, который могут считывать/изменять middleware, расположенные ниже.
Как и во всех фреймворках, правильная обработка ошибок имеет решающее значение. В Express вы должны создать специальный промежуточный обработчик - middleware с четырьмя входными параметрами:
const express = require('express')
const app = express()
app.get('/', (request, response) => {
throw new Error('oops')
})
app.use((err, request, response, next) => {
// логирование ошибки, пока просто console.log
console.log(err)
response.status(500).send('Something broke!')
})
app.listen(3000)
Что следует здесь отметить:
- Обработчик ошибок должен быть последней функцией, добавленной с помощью
app.use
. - Обработчик ошибок принимает коллбек
next
. Он может использоваться для объединения нескольких обработчиков ошибок.
Ранее мы рассмотрели, как отправлять JSON-ответы. Пришло время узнать, как отрендерить HTML простым способом. Для этого мы собираемся использовать пакет handlebars с обёрткой express-handlebars.
Сначала создадим следующую структуру каталогов:
├── index.js
└── views
├── home.hbs
└── layouts
└── main.hbs
После этого заполните index.js
следующим кодом:
// index.js
const path = require('path')
const express = require('express')
const exphbs = require('express-handlebars')
const app = express()
app.engine('.hbs', exphbs({
defaultLayout: 'main',
extname: '.hbs',
layoutsDir: path.join(__dirname, 'views/layouts')
}))
app.set('view engine', '.hbs')
app.set('views', path.join(__dirname, 'views'))
app.listen(3000)
Приведенный выше код инициализирует движок handlebars и устанавливает каталог шаблонов в views/layouts
. Это каталог, в котором будут храниться ваши шаблоны.
После того, как вы сделали эту настройку, вы можете поместить свой начальный html
в main.hbs
. Чтобы всё было проще, давайте сразу перейдём к этому:
<html>
<head>
<title>Express handlebars</title>
</head>
<body>
{{{body}}}
</body>
</html>
Вы можете заметить метку {{{body}}}
— здесь будет размещен ваш контент. Давайте создадим home.hbs
!
<h2>Hello {{name}}</h2>
Последнее, что мы должны сделать, чтобы заставить всё это работать, - добавить обработчик маршрута в наше приложение Express:
app.get('/', (request, response) => {
response.render('home', {
name: 'John'
})
})
Метод render
принимает два параметра:
- Первый — это имя шаблона.
- Второй — данные, необходимые для рендеринга.
Как только вы сделаете запрос по этому адресу, вы получите что-то вроде этого:
<html>
<head>
<title>Express handlebars</title>
</head>
<body>
<h2>Hello John</h2>
</body>
</html>
Это всего лишь верхушка айсберга. Чтобы узнать, как добавить больше шаблонов (и даже частичных), обратитесь к официальной документации express-handlebars.
В некоторых случаях вам может потребоваться выяснить, что происходит с Express, когда приложение работает. Для этого вы можете передать следующую переменную окружения в Express: DEBUG=express*
.
Вы должны запустить свой Node.js HTTP-сервер, используя:
$ DEBUG=express* node index.js
Вот как вы можете настроить свой первый HTTP-сервер на Node.js с нуля. Я рекомендую Express для начала, а затем поэкспериментируйте.
В следующей главе вы узнаете, как получать информацию из баз данных.
Слушайте наш подкаст в iTunes и SoundCloud, читайте нас на Medium, контрибьютьте на GitHub, общайтесь в группе Telegram, следите в Twitter и канале Telegram, рекомендуйте в VK и Facebook.