В следующей главе вы узнаете основы HTTP и как вы можете получать ресурсы из внешних источников с помощью модуля Node.js request.

This article was translated to Russian by Andrey Melikhov, a front-end developer from Yandex.Money and editor of the collective blog about front-end, devSchacht. Find Andrey on: Twitter, GitHub, Medium & SoundCloud

Read the original article in English: Node.js request module tutorial.

Перевод этой статьи сделан Андреем Мелиховым, фронтенд-разработчиком из компании Яндекс.Деньги, редактором коллективного блога о фронтенде, devSchacht. Twitter | GitHub | Medium | SoundCloud



Что такое HTTP?

HTTP - это протокол передачи гипертекста. HTTP функционирует как протокол запроса-ответа в модели клиент-сервер.

Коды состояния HTTP

Прежде чем погрузиться в общение с другими API-интерфейсами, давайте рассмотрим коды состояния HTTP, с которыми мы можем столкнуться во время работы нашего приложения. Они описывают результаты наших запросов и очень важны для обработки ошибок.

  • 1xx — Информационный
  • 2xx — Успех: Эти коды состояния говорят о том, что наш запрос был получен и обработан правильно. Наиболее распространённые коды успеха - 200 OK, 201 Created и 204 No Content.
  • 3xx — Редирект: Эта группа кодов показывает, что клиент должен будет выполнить дополнительные действия для завершения запроса. Наиболее распространёнными кодами перенаправления являются 301 Moved Permently, 304 Not Modified.
  • 4xx — Ошибка клиента. Этот класс кодов состояния используется, когда запрос, отправленный клиентом, содержит какую-то ошибку. Ответ сервера обычно содержит объяснение ошибки. Наиболее распространёнными кодами ошибок клиента являются 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 409 Conflict.
  • 5xx - Ошибка сервера: эти коды отправляются, когда сервер не смог выполнить корректный запрос из-за какой-то ошибки. Причиной может быть ошибка в коде или некоторая временная или постоянная неисправность. Наиболее распространённые коды ошибок сервера: 500 Internal Server Error, 503 Service Unavailable. Если вы хотите узнать больше о кодах состояния HTTP, вы можете найти подробное объяснение здесь.

Отправка запросов внешним API

Подключение к внешним API-интерфейсам — простая задача в Node. Вы можете просто подключить базовый модуль HTTP и начать отправку запросов.

Конечно, есть намного лучшие способы обращения к внешним API. В NPM вы можете найти несколько модулей, которые облегчат вам этот процесс. Например, двумя наиболее популярными являются модули request и superagent.

Оба этих модуля имеют первый интерфейс построенный на колбеках, который может привести к некоторым проблемам (я уверен, вы слышали о Callback-Hell), но, к счастью, у нас есть доступ к версиям обёрнутым в промисы.

Использование модуля Request

Использование модуля request-promise — это очень просто. После его установки из NPM, вам нужно только подключить его к программе:

const request = require('request-promise')

Отправка GET-запроса:

const options = {
    method: 'GET',
    uri: 'https://risingstack.com'
}

request(options)
    .then(function (response) {
        // Запрос был успешным, используйте объект ответа как хотите
    })
    .catch(function (err) {
        // Произошло что-то плохое, обработка ошибки
    })

Если вы вызываете JSON API, вам может потребоваться, чтобы request-promise автоматически распарсил ответ. В этом случае просто добавьте это в параметры запроса:

json: true

POST-запросы работают аналогичным образом:

const options = {
    method: 'POST',
    uri: 'https://risingstack.com/login',
    body: {
       foo: 'bar'
    },
    json: true
    // Тело запроса приводится к формату JSON автоматически
}

request(options)
    .then(function (response) {
        // Обработка ответа
    })
    .catch(function (err) {
        // Работа с ошибкой
    })

Чтобы добавить параметры строки запроса, вам просто нужно добавить свойство qs к объекту options:

const options = {
    method: 'GET',
    uri: 'https://risingstack.com',
    qs: {
        limit: 10,
        skip: 20,
        sort: 'asc'
    }
}

Этот код соберёт следующий URL для запроса: https://risingstack.com?limit=10&skip=20&sort=asc. Вы также можете назначить любой заголовок так же, как мы добавили параметры запроса:

const options = {
    method: 'GET',
    uri: 'https://risingstack.com',
    headers: {
        'User-Agent': 'Request-Promise',
        'Authorization': 'Basic QWxhZGRpbjpPcGVuU2VzYW1l'
    }
}

Обработка ошибок

Обработка ошибок - это неотъемлемая часть запросов на внешние API, поскольку мы никогда не можем быть уверены в том, что с ними произойдёт. Помимо наших ошибок клиента сервер может ответить с ошибкой или просто отправить данные в неправильном или непоследовательном формате. Помните об этом, когда вы пытаетесь обработать ответ. Кроме того, использование catch для каждого запроса - хороший способ избежать сбоя на нашем сервере по вине внешнего сервиса.

Объединяем всё вместе

Поскольку вы уже узнали, как развернуть HTTP-сервер на Node.js, как отрисовать HTML и как получить данные из внешних API, пришло время собрать эти знания вместе!

В этом примере мы собираемся создать небольшое приложение на Express, которое может отображать текущие погодные условия на основе названий городов.

(Чтобы получить ключ для API AccuWeather, посетите их сайт для разработчиков)

const express = require('express')
const rp = require('request-promise')
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.get('/:city', (req, res) => {
    rp({
        uri: 'http://apidev.accuweather.com/locations/v1/ search',
        qs: {
            q: req.params.city,
            apiKey: 'api-key'
                // Используйте ваш ключ для accuweather API
        },
        json: true
    })
    .then((data) => {
        res.render('index', data)
    })
    .catch((err) => {
        console.log(err)
        res.render('error')
    })
})

app.listen(3000)

Пример выше делает следующее:

  • создаёт Express-сервер
  • устанавливает handlebars в качестве шаблонизатора
  • отправляет запрос к внешнему API
    • если все в порядке то приложение отображает страницу
    • в противном случае приложение показывает страницу неудачи и регистрирует ошибку

В следующей главе Node Hero вы узнаете, какая файловая структура предпочтительней в Node.js проектах.