Введение

В этом блоге я покажу вам, как создать сервер NodeJS, используя модуль core http. Мы создадим простой сервер, который будет обслуживать статические ресурсы, и простой API для возврата некоторых данных JSON.

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

Предпосылки

  1. NodeJS установлен в вашей системе. Скачать с Здесь
  2. Базовое понимание 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, предоставляемый модулем node http. 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.