В последние три года мы наблюдаем всплеск популярности JavaScript. За прошедшие годы было предпринято множество попыток перенести популярный язык на сервер . Наиболее распространенной из этих попыток был Node.js , который был представлен сообществу как быстрый способ написания серверных приложений. Точкой продаж для Node была скорость, как с точки зрения производительности, так и времени разработки. С такой популярностью сообщество росло, и проект получил больше участников, что привело к созданию высококачественных модулей, таких как Express.js .
В результате люди начали создавать законченные бэк-энды, используя Node. Одна из самых важных вещей, которую должна выполнять внутренняя система, — это эффективная связь с базами данных. Вот где приходит программное обеспечение Object-Relational Mapping или ORM. Обычно разработчики должны хорошо владеть языком программирования, который они используют, и SQL, чтобы взаимодействовать с базами данных. ORM упрощают жизнь, позволяя разработчикам взаимодействовать с базами данных на выбранном ими языке программирования с помощью объектов. Эта статья знакомит с ORM и рассматривает ORM Bookshelf.js.
Что такое ORM?
Википедия определяет объектно-реляционное отображение как:
техника программирования для преобразования данных между несовместимыми типами
системы в объектно-ориентированных языках программирования. Это создает, в
эффект, «база данных виртуальных объектов», которая может быть использована из
язык программирования
Теперь в нашем случае язык программирования — это JavaScript, а несовместимая система — это система реляционных баз данных, такая как MySQL. Это означает, что библиотека ORM должна позволять нам взаимодействовать с базой данных так же, как мы взаимодействуем с обычными объектами JavaScript. Существует множество библиотек ORM для Node.js, популярными из которых являются Persistence.js , Sequelize.js и Bookshelf.js . Эта статья представит Bookshelf.js.
Bookshelf.js Примеры
Взаимодействие с базой данных обычно сосредоточено вокруг четырех операций CRUD — создание, чтение, обновление и удаление. Bookshelf.js предоставляет интуитивно понятный способ сделать это, например, вот так будет выглядеть операция создания:
new Post({name: 'New Article'}).save().then(function(model) { // ... });
Предполагая, что Post
является моделью, которая имеет соответствующую таблицу базы данных, а это name
является атрибутом, который соответствует столбцу в таблице базы данных.
Аналогично, операция чтения выглядит следующим образом:
// select * from `user` where `email` = '[email protected]' new User({email: '[email protected]'}) .fetch() .then(function(model) { console.log(model.get('gender')); });
Обратите внимание на вызов в коде. Bookshelf.js поддерживает основанные на обещаниях интерфейсы, что в данном случае означает, что переданная анонимная функция будет вызываться, только если ваш запрос был успешным. model
представляет собой результирующий объект JavaScript, который можно использовать для доступа к атрибутам, связанным с User
. В нашем случае model.get('gender')
возвращает пол нашего пользователя.
Создание API с помощью Bookshelf.js и Express.js
Для более полного примера, предположим, что нам было поручено создать JSON API для блога со следующими ресурсами:
GET /api/article GET /api/article/:article_id POST /api/article
И клиент уже имеет базу данных MySQL со следующей таблицей:
create table article ( id int not null primary key, title varchar(100) null, body text null, author varchar(100) null );
Для начала нам нужно настроить нашу среду Express.js с помощью package.json
:
{ "name": "article_api", "description": "expose articles via JSON", "version": "0.0.1", "private": true, "dependencies": { "bluebird": "^2.1.3", "body-parser": "^1.3.1", "express": "4.4.3", "mysql": "*", "knex": "*", "bookshelf": "*" } }
Нам нужен knex
запросов knex
потому что от него зависит bookshelf
, а для обещаний нам нужен bluebird
.
Наша структура app.js
теперь выглядит так:
// When the app starts var express = require('express'); var app = express(); var bodyParser = require('body-parser'); var Promise = require('bluebird'); var dbConfig = { client: 'mysql', connection: { host: 'localhost', user: 'root', password: 'your_password', database: 'blog', charset: 'utf8' } }; var knex = require('knex')(dbConfig); var bookshelf = require('bookshelf')(knex); app.set('bookshelf', bookshelf); var allowCrossDomain = function(req, res, next) { res.header('Access-Control-Allow-Origin', '*'); next(); }; app.use(allowCrossDomain); // parse application/x-www-form-urlencoded app.use(bodyParser.urlencoded()); // parse application/json app.use(bodyParser.json()); // parse application/vnd.api+json as json app.use(bodyParser.json({type: 'application/vnd.api+json'})); // elsewhere, to use the bookshelf client: var bookshelf = app.get('bookshelf'); // {our model definition code goes here} app.listen(3000, function() { console.log('Express started at port 3000'); });
Наша база данных MySQL называется blog
. Нам нужно определить модель товара и привязать ее к таблице article
. Мы заменим // {our model definition code goes here}
:
var Article = bookshelf.Model.extend({ tableName: 'article' });
Хотите верьте, хотите нет, но это все, что нужно для определения модели в Bookshelf.js. Теперь мы можем использовать эту модель для запроса базы данных в нашем API. Для начала метод GET /api/article
должен возвращать все статьи в базе данных:
app.get('/api/article', function(req, res) { new Article().fetchAll() .then(function(articles) { res.send(articles.toJSON()); }).catch(function(error) { console.log(error); res.send('An error occured'); }); });
fetchAll
в Bookshelf.js извлекает все записи в таблице базы данных, а catch
выполняется только в случае ошибки (в документации есть больше методов модели).
Вывод
Node.js вырос как технология и может использоваться для создания веб-приложений и API через такие модули, как Express.js. Bookshelf.js упрощает взаимодействие с реляционной базой данных с помощью приложения Node.js, оборачивая базовую структуру таблицы базы данных и выставляя обычные объекты JavaScript для запросов. Эта статья обеспечила введение высокого уровня. Полная реализация демонстрационного проекта доступна на GitHub .