Экспресс-бой (6): создание API-интерфейса

Node.js JavaScript Express

Cover
Cover

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

По сути, API — это способ взаимодействия между кодами, которое может осуществляться внутри программы или между машинами по сети. Например, в экспрессapp.useиapp.getЭто относится к внутреннему использованию API. К последним относится способ отправки данных JSON и XML через такие протоколы, как HTTP или FTP. Для последнего метода следует отметить, что поставщик и пользователь API должны заключить соглашение о формате данных. В этом примере мы обсудим, как использовать Express для создания интерфейса API последнего типа, и все форматы данных, возвращаемые интерфейсом HTTP, будут использовать JSON.

Кроме того, в этой главе также обсуждаются, как разработать элегантную API для повышения опыта и эффективности пользователя, так что значение API не читает вонючие и длительные объяснения документов. Как и «хороший код», как «плохой код», является ли API элегантным. Он на самом деле больше зависит от реальной ситуации. Лучшие практики, которые слепо следят за дизайном API, иногда выглядят очень парализованно, потому что это может быть несовместимо с ожиданиями пользователя.

Далее следует:

  • Что такое API.
  • Основы создания API в Express.
  • Связь методов HTTP с логикой приложения.
  • Внедрение и управление многоверсионными API.
  • Правильное использование кодов состояния HTTP.

Пример простого API в формате JSON

Во-первых, нам нужен наглядный пример функции и использования API, напишите код позади.

Предположим, теперь, когда программе нужно получитьAmerica/Los_AngelesилиEurope/LondonПосле ожидания строки, представляющей часовой пояс, верните текущую информацию о времени часового пояса (например:2015-04-07T20:09:58-07:00). Возвращаемая информация не совпадает с форматом времени, который легко понять на самом деле, поскольку он предназначен для компьютеров.

API приложения вызывается через HTTP-запрос с URL-адресом следующего формата:

/timezone?tz=America+Los_Angeles

Формат данных JSON, возвращаемый серверным API, выглядит следующим образом:

{
    "time": "2015-06-09T16:20:00+01:00",
    "zone": "America/Los_Angeles"
}

Пока вы можете вызывать API и анализировать данные JSON, вы можете создать любое приложение на любой платформе. Как показано на рисунке ниже, вы можете запросить этот API через AJAX для реализации одностраничного приложения, которое отображает информацию о часовом поясе.

06_01
06_01

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

06_02
06_02

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

06_03
06_03

Как и в случае с погодным приложением из предыдущей главы, мы можем использовать ледяные данные, возвращаемые этими API, для создания более выразительных пользовательских интерфейсов.

Экспресс-сервис JSON API

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

С технической точки зрения служба API также может использовать XML или простой текст в дополнение к формату JSON. Но поддержка Express и JavaScript для JSON - лучшая, и это также самый популярный формат, поэтому он всегда будет использовать JSON в качестве формата данных по умолчанию.

Давайте напишем сервис, обеспечивающий генерацию случайных чисел для нескольких платформ, API будет иметь следующие возможности:

  • Значения nonce min и max должны быть включены при запросе API.
  • Разберите запрос, чтобы получить диапазон случайных чисел, и верните полученный результат в формате JSON.

Вы можете подумать, что здесь можно использовать обычный текст вместо JSON. Но отправка данных JSON является важным навыком для разработчиков, а формат JSON чрезвычайно расширяем.

Этапы строительства этого проекта следующие:

  1. новыйpackage.json.
  2. Создать основной файл ввода проектаapp.js.
  3. существуетapp.jsСоздайте промежуточное ПО для приложений и маршрутизации в .

Во-первых, во вновь созданномpackage.json, скопируйте следующее и следуйте зависимостям:

{
    "name": "random-number-api",
    "private": true,
    "scripts": {
        "start": "node app"
    },
    "dependencies": {
        "express": "^5.0.0" 
    }
}

Затем скопируйте файл на вход следующего кодаapp.jsсередина:

var express = require("express");
var app = express();

app.get("/random/:min/:max", function(req, res) {
    var min = parseInt(req.params.min);
    var max = parseInt(req.params.max);
    if (isNaN(min) || isNaN(max)) {
        res.status(400);
        res.json({ error: "Bad request." });
        return;
    }

    var result = Math.round((Math.random() * (max - min)) + min);
    res.json({ result: result });
});

app.listen(3000, function() {
    console.log("App started on port 3000");
});

Теперь запустите приложение и получите доступhttp://localhost:3000/random/10/100Если вы это сделаете, вы увидите данные JSON со случайными числами в диапазоне 10-100.

06_04
06_04

Далее давайте проанализируем приведенный выше код.

Как и прежде, первые две строки кода представляют Express и создают экземпляр приложения Express.

Затем мы создали промежуточное программное обеспечение маршрутизации для обработки чего-то вроде/random/10/100Такой запрос API. Конечно, есть еще некоторая ошибка, например, не фильтруется/random/foo/barпросить. Поэтому при вызове API убедитесь, что используемые параметры являются целочисленными переменными.

Затем мы используем встроенныйparseIntПроанализируйте параметр диапазона, и возвращаемое значение функции может быть только целым числом или NaN. Если один из переданных параметров имеет значение NaN, клиенту будет возвращено сообщение об ошибке. Следующая часть кода очень важна для всей программы:

if (isNaN(min) || isNaN(max)) {
  res.status(400);
  res.json({ error: "Bad request." });
  return;
}

Если результатом вышеуказанной проверки параметров является то, что хотя бы один из них равен NaN, программа будет действовать следующим образом:

  1. Установите код состояния HTTP на 400. Распространенная ошибка 404 — это ее конкретный вариант, означающий, что возникла проблема с запросом пользователя.
  2. Отправьте данные JSON, содержащие сообщения об ошибках.
  3. Остановить обработку запроса и выйти из выполнения промежуточного программного обеспечения.

В конце кода мы генерируем случайное число в допустимом параметре return и возвращаем результат клиенту.

Хотя пример прост, он уже охватывает основной процесс создания API с помощью Express: анализ запроса, установка кода состояния HTTP и возврат данных ответа. Вы можете создавать более сложные и элегантные API поверх этого.

API операции CURD

CURD — это аббревиатура четырех бизнес-операций: «Создать», «Читать», «Обновить» и «Удалить» в программе.

Большинство приложений включают операции творога. Например, для приложения для совместного использования изображений все операции, связанные с изображениями, являются типичными CRUD:

  • Поведение пользователей при загрузке фотографий, соответствующихcreateработать.
  • Поведение пользователей, просматривающих фотографии,readработать.
  • Поведение пользователя обновлено фотоupdateработать.
  • Действие по удалению фото пользователемdeleteработать.

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

HTTP-метод

Спецификация HTTP определяет его методы следующим образом:

Методы HTTP указывают, что делать с ресурсом, идентифицированным URI запроса, а методы чувствительны к регистру.

Более понятное объяснение состоит в том, что клиенту нужно указать метод HTTP при отправке HTTP-запроса, а затем сервер отвечает по-разному в соответствии с разными методами HTTP. Хотя существует много доступных HTTP-методов, не многие из них широко используются. Среди них следующие четыре обычно используются в веб-приложениях:

  1. GET — один из наиболее часто используемых методов HTTP, что означает запрос ресурсов на стороне сервера. Например, GET используется для загрузки домашней страницы веб-сайта и запроса ресурсов изображения. Хотя ответ сервера может быть другим, запрос GET не изменяет ресурсы сервера. Например, один или несколько запросов ресурса изображения не вызовут никаких изменений в самом изображении.
  2. POST — еще один широко используемый метод HTTP. Например, для создания новых блогов, загрузки фотографий, зарегистрированных пользователей и пустых корзин покупок и т. д. используется POST. В отличие от Get: каждый запрос POST приводит к изменению сервера.
  3. Метод PUT используется для внесения изменений в существующие записи, поэтому я думаю, что его более уместно называть «ОБНОВЛЕНИЕ». Например, такие операции, как изменение названия блога и изменение псевдонима пользователя, являются операциями PUT. Кроме того, PUT также имеет функцию POST: то есть, когда запись, которую нужно изменить, не существует, может быть выполнена новая операция (не требуется). Во-вторых, PUT также имеет характеристики метода GET: результаты одного или нескольких запросов PUT к одному и тому же URL-адресу согласуются.
  4. Метод DELETE используется для удаления записи. Например, удалить пользовательские статьи, удалить веб-фотографии. Кроме того, как и в случае с PUT, окончательный результат не зависит от того, выполняется ли один и тот же запрос на удаление один или несколько раз.

Хотя существует множество других методов HTTP, они не очень распространены в реальном процессе разработки. Теоретически вы могли бы делать все, используя только запросы GET и POST, но это плохая практика, ведь она нарушает спецификацию HTTP и может вызвать путаницу у разработчиков. Кроме того, многие браузеры также указывают тип выполняемой операции на основе метода HTTP. Поэтому, даже если она не соблюдается, вы должны ссылаться на эту норму, чтобы управлять своим поведением.

Вы видели обработку некоторых методов в Express ранее, но следующий код будет охватывать все четыре из вышеупомянутых методов одновременно:

var express = express("express");
var app = express();

app.get("/", function(req, res) {
  res.send("you just sent a GET request, friend");
});

app.post("/", function(req, res) {
  res.send("a POST request? nice");
});

app.put("/", function(req, res) {
  res.send("i don't see a lot of PUT requests anymore");
});

app.delete("/", function(req, res) {
  res.send("oh my, a DELETE??");
});

app.listen(3000, function() {
  console.log("App is listening on port 3000");
});

Скопируйте код в файл записиapp.jsи запустите службу, затем вы можете использовать команду cURL для тестирования различных методов HTTP. По умолчанию cURL использует GET для отправки запросов, но вы можете использовать параметр -X для указания других методов. Например,curl -X PUT http://localhost:3000.

06_05
06_05

Построение CRUD-интерфейсов с помощью HTTP-методов

Вспомните приведенные ниже приложения для обмена фотографиями, и вот возможные операции CRUD:

  1. Пользователи загружают фотографии, этоCreate.
  2. Пользователи просматривают изображение, этоRead.
  3. Пользователь обновляет примечания к картинкам и другую информацию, этоUpdate.
  4. Пользователь удаляет изображение с сайта, этоDelete.

Нетрудно заметить, что операции CRUD соответствуют предыдущим четырем методам HTTP:

  • Create = POST
  • Read = GET
  • Update = PUT
  • Delete = DELETE

Таким образом, с помощью этих четырех HTTP-методов мы можем реализовать наиболее распространенные веб-приложения в стиле CRUD.

На самом деле, у некоторых людей есть свое мнение о том, как действия update и create соответствуют методам HTTP. Они считают, что PUT должен быть скорее действием создания, чем POST. Кроме того, новый метод PATCH соответствует операции обновления. Хотя в этой статье будет использоваться более официальная переписка, описанная выше, вы можете выбрать ее по своему усмотрению.

Версии API

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

/v1/timezone

Запрос API новой версии может использовать:

/v2/timezone

Это не только предотвращает критические изменения кода при обновлении API. У пользователей интерфейса также есть более гибкие возможности, и они могут переключать API, когда это необходимо.

В Express вы можете использовать промежуточное ПО Router для реализации управления версиями API. Скопируйте следующий код в файлapp1.js, и рассказать о его реализации в качестве первой версии API:

var express = require("express");
var api = express.Router();

api.get("/timezone", function(req, res) {
    res.send("Sample response for /timezone");
});
api.get("/all_timezones", function(req, res) {
    res.send("Sample response for /all_timezones");
});

module.exports = api;

Обратите внимание, что приведенный выше промежуточный код обрабатывает URL-адреса, которые не содержат/v1.下面在入口文件中引入这个 Router 中间件并进行路由映射。

var express = require("express");
var apiVersion1 = require("./api1.js");
var app = express();
app.use("/v1", apiVersion1);
app.listen(3000, function() {
    console.log("App started on port 3000");
});

Затем вы поставили последнюю версию APIapi2.jsВ файле:

var express = require("express");
var api = express.Router();

api.get("/timezone", function(req, res) {
    res.send("API 2: super cool new response for /timezone");
});
module.exports = api;

Наконец, добавьте обе версии API в основную запись через Router:

var express = require("express");

var apiVersion1 = require("./api1.js");
var apiVersion2 = require("./api2.js");
var app = express();

app.use("/v1", apiVersion1);
app.use("/v2", apiVersion2);
app.listen(3000, function() {
    console.log("App started on port 3000");
});

Вы можете убедиться, что эти версионные API работают правильно через ваш браузер, а также протестировать их с помощью команд cURL.

06_07
06_07

Как описано в предыдущей главе, Router позволяет вам управлять разными маршрутами в разных файлах. Версионный API — наиболее типичный пример приложения.

Установить код состояния HTTP

Каждый ответ HTTP должен сопровождаться кодом состояния HTTP, наиболее известным из которых является404 Not Found.

В то время как 404 является наиболее известным, код состояния 200 действительно является наиболее распространенным. В отличие от 404, хотя код состояния 200 включается, когда веб-страница успешно загружается или данные JSON успешно возвращаются, он не отображается.

Конечно, кроме 404 и 200, в HTTP определено много других кодов состояния, включая серии 100, 200, 300, 400 и 500. Следует отметить, что не все 100 номеров в каждой серии четко определены, например, 100 серия имеет только три действительных кода: 100, 101, 102, за которыми следует 200.

Каждая серия кодов состояния на самом деле имеет определенное значение и тему.

1xx: запрос успешно получен.
2xx: успех
3xx: перенаправление
4xx: ошибка клиента
5xx: ошибка сервера

В спецификации определено только около 60код состояния. Вы можете расширить свои собственные коды состояния поверх этого, но обычно вы этого не делаете. Поскольку первый принцип разработки хорошего API заключается в том, чтобы гарантировать отсутствие двусмысленности для пользователей, он должен в максимально возможной степени следовать указаниям официальной спецификации. Мы объясним коды состояния для каждого из вышеуказанных интервалов позже, но перед этим давайте посмотрим, как установить коды состояния в Express.

Небольшое количество приложений по-прежнему использует версию протокола HTTP 1.0, в то время как большинство перешли на версию 1.1. Как следующая версия стандарта HTTP 2.0, он также постепенно продвигается. К счастью, большинство обновлений протокола 2.0 находятся в самом низу, поэтому переключение не требует особых усилий. Кроме того, в версии 2.0 также добавлен код состояния 421.

Установить код состояния HTTP

По умолчанию код состояния HTTP составляет 200. Если URL-адрес URL-адреса соответствует ресурсу, не существует, Express отправляет ошибку 404. Если у вас возникнут проблема с сервером, который возникает, Express отправляет 500 ошибку.

Но это выражение поведения по умолчанию, вам может потребоваться установить свой собственный код состояния в некоторых случаях. По этой причине Экспрессresponseобъект обеспечиваетstatusметод, вам необходимо передать соответствующий код состояния в вызове, чтобы завершить настройку.

// ...
res.status(404);
// ...

Этот метод можно объединить в цепочку, поэтому вы можете использовать его сразу послеjsonУстановите возвращаемые данные.

res.status(404).json({ error: "Resource not found!" });
// 它等价于:
res.status(404);
res.json({ error: "Resource not found!" });

Хотя у Экспресса естьresponseОбъекты расширены и должны следовать в экспресс-стиле при использовании Express, но вы все равно можете использовать нативные методы для завершения настройки.

res.statusCode = 404;

100 интервал

Официальных кодов состояния для 100-го интервала всего два: 100 (продолжение) и 101 (переключение протокола), и они редко используются. Если вам приходится иметь с этим дело, вы можете зайти на официальный сайт или вики, чтобы проверить.

200 интервал

Код состояния интервала 200 указывает на то, что запрос выполнен успешно. Хотя в этом интервале есть много кодов состояния, обычно используются следующие четыре:

  • 200: как наиболее распространенный код состояния, он также называется «ОК». Это означает, что запрос и ответ были выполнены правильно, без каких-либо ошибок или редиректов.
  • 201: очень похоже на 200, но используется немного по-другому. Обычно он используется после поста или запроса на поставку успешно создал запись. Например, 201 отправляется, когда операция, такая как создание поста в блоге, загрузка изображения и т. Д. Успешна.
  • 202: 202 — это вариант 201. Потому что, большая часть создания ресурсов осуществляется асинхронно, и эти операции тоже берутся. Итак, вы можете ответить клиенту в это время. Это указывает на то, что данные были успешно получены и ожидают создания.
  • 204: указывает, что ресурс, соответствующий запросу пользователя на удаление, не существует и был удален.

300 диапазон

Опять же, в диапазоне 300 мы рассматриваем только три из них, которые обычно используются, и все они включают перенаправления.

  • 301: Это означает, что расположение ресурса, к которому осуществляется доступ, было изменено. Пожалуйста, перейдите по последнему URL-адресу. Обычно он также поставляется с заголовком Location, указывающим, куда перенаправить.
  • 303: Это означает, что запрошенный ресурс создан, и теперь вы будете перенаправлены на новую страницу.
  • 307: Подобно 301, это означает, что текущий URL-адрес не существует. Разница в том, что переадресация 301 является постоянной, а переадресация 307 может быть только временным URL-адресом.

Раздел 400

Раздел кода состояния 400 является самым большим и обычно представлен ошибкой, поскольку запрос клиента не выполнен.

  • 401 и 403: эти два кода статуса указывают «несанкционированные» и «запрет». Посмотрите на два очень похоже, но первый может указывать на то, что пользователь не вошел в систему, и последний может быть логин пользователя, но разрешения недостаточно.
  • 404: Это указывает на то, что ресурс, запрошенный URL-адресом пользователя, не существует.

Что касается других кодов статуса в этом интервале, читатели могут перейти квикиПроверьте это сами, я не буду представлять их здесь по одному. Кроме того, если вы не уверены, какой код состояния ошибки клиента вам следует использовать, вы можете просто использовать 400 .

500 диапазон

В качестве последнего диапазона в спецификации HTTP код состояния состояния 500 интервала указывает на ошибку в сервисе внутри. Например, перегрузка запросов или соединение базы данных прерывается. Кроме того, теоретическая ошибка может быть вызвана только внутри сервиса. Наконец, чтобы предотвратить слишком много внутренней информации хакеров, вы можете только вернуть информацию, такой как «Ошибка внутреннего сервера» для всех внутренних ошибок.

Суммировать

В эту главу входят:

  • Создавайте сервисы API с помощью Express.
  • HTTP-методы и их отношения к операциям CRUD.
  • Если контроль версий API, подскажите совместимость и стабильность службы.
  • Использование кода состояния HTTP и его значение.

оригиналадрес