Введение
В этом блоге я покажу вам, как создать сервер NodeJS, используя модуль core http. Мы создадим простой сервер, который будет обслуживать статические ресурсы, и простой API для возврата некоторых данных JSON.
В процессе вы также узнаете об объектах запроса и ответа, предоставляемых NodeJS, которые используются всеми другими фреймворками, построенными поверх NodeJS, такими как ExpressJS и т. д.
Предпосылки
- NodeJS установлен в вашей системе. Скачать с Здесь
- Базовое понимание JavaScript
Имея это в виду, давайте начнем.
Шаг 1: Инициализируйте проект
- Создайте папку с любым именем и инициализируйте в ней нод-проект с помощью
npm init -y
К этому времени у вас будет файл package.json
в вашем каталоге.
- Создайте файл с именем
server.js
в своем каталоге.
Шаг 2. Добавьте статический контент.
- Создайте каталог с именем
public
в корне вашего проекта. - Добавьте файл с именем
index.html
со следующим содержимымindex.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Demo</title>
</head>
<body>
<h1>Coming from the Root </h1>
</body>
</html>
Шаг 3: Добавьте код нашего сервера для обслуживания статических ресурсов.
Теперь мы создадим сервер узла, который будет обслуживать наш файл index.html
при отправке запроса на /
.
server.js
const http = require('http'); const path = require('path'); const fs = require('fs'); const PORT = 3000; const hostname = 'localhost';
// createServer is the http method used to create a web server that takes a callback. const server = http.createServer(serverHandler);
// callback function definition function serverHandler(req, res) => { if(req.method === 'GET' && req.url === '/') { let filePath = path.resolve(__dirname, 'public/index.html') let fileExists = fs.existsSync(filePath); if (!fileExists) { res.statusCode = 404; res.setHeader('Content-Type', 'text/html'); res.end(` <html> <body> <h3>Page not found</h3> </body> </html>`) } else { res.statusCode = 200; res.setHeader('Content-Type', 'text/html'); fs.createReadStream(filePath).pipe(res); } } }
server.listen(PORT, hostname, () => { console.log(`Server running at ${hostname}:${PORT}`); })
Давайте разберемся, что только что произошло в приведенном выше фрагменте кода:
- Прежде всего, мы только что создали сервер, используя метод
createServer
, предоставляемый модулем nodehttp
.createServer
принимает обратный вызов, который будет вызываться при поступлении входящего запроса с параметрамиreq
иres
. - В нашей функции обратного вызова
serverHandler
мы использовали блокif
, чтобы проверить, является ли входящий запрос запросомGET
, а запросurl
является/
, после чего будет выполнен код внутри оператора if. - Затем мы проверяем, существует ли
index.html
, который мы хотим обслуживать, в нашем общедоступном каталоге, используяexistsSync
, который синхронно проверяет наличие файла по заданному пути и возвращает true, если файл существует. - Затем, если файл не существует, мы возвращаем статус 404 с ответом HTML с заголовком Content-Type, чтобы сообщить браузеру, что это ответ типа HTML.
- Если файл существует, мы создаем из него читаемый поток, используя метод
createReadStream
из модуляfs
, и передаем его в объектres
, который отправляет его в браузер. - Наконец, мы используем
server.listen
для запуска нашего сервера на ПОРТ 3000.
Теперь пришло время протестировать наш сервер. Запустите node server.js
в корне проекта, и вы увидите сервер, работающий на ПОРТУ 3000. Откройте браузер и введите localhost:3000
в адресной строке, и вы получите ответ в формате HTML.
Шаг 4. Добавьте базовый API для возврата некоторых данных JSON.
Теперь мы расширим наш обратный вызов, который мы передали в createServer
, чтобы обработать еще один запрос GET
в /notes
, который вернет браузеру массив заметок.
Обновите функцию serverHandler
, добавив в файл server.js
следующий фрагмент кода.
server.js
... function serverHandler(req, res) { if(req.method === 'GET' && req.url === '/') { let filePath = path.resolve(__dirname, 'public/index.html') let fileExists = fs.existsSync(filePath); if (!fileExists) { res.statusCode = 404; res.setHeader('Content-Type', 'text/html'); res.end(` <html> <body> <h3>Page not found</h3> </body> </html>`) } else { res.statusCode = 200; res.setHeader('Content-Type', 'text/html'); fs.createReadStream(filePath).pipe(res); } } // Newly added code if (req.method === 'GET' && req.url === "/notes") { const notes = [ { id: 1, title: "Demo Note" }, { id: 2, title: "Another Note" } ]
res.statusCode = 200; res.setHeader('Content-Type', 'application/json'); res.end(JSON.stringify(notes)); } else { res.setHeader('Content-Type', 'application/json') res.end(JSON.stringify({message: `${req.method} is not supported for ${req.url}`})) } } ...
- Здесь мы добавили еще один оператор
if
для обработки запроса, поступающего по адресу/notes
. - Мы возвращаем массив заметок в формате JSON и устанавливаем для заголовка Content-Type значение
application/json
, чтобы браузер обрабатывал его соответствующим образом. - Мы также добавили оператор else для обработки всех остальных запросов, когда мы просто возвращаем браузеру сообщение о том, что запрос не поддерживается.
При этом мы создали простой сервер узлов для обслуживания статического контента, а также простой API для возврата данных JSON.
Вывод
Мы увидели, как нам приходилось обрабатывать каждый запрос с его методом и URL-адресом. С увеличением количества маршрутов такими вещами становится трудно управлять, поскольку нам придется добавлять несколько операторов if. И именно поэтому существуют такие фреймворки, как ExpressJS, HapiJS, что делает создание серверов в NodeJS очень простым. Но важно знать, что происходит под капотом, поскольку в этих фреймворках не происходит волшебства.
Полный код этого блога можно найти на Github Repo.
Первоначально опубликовано на https://www.loginradius.com.