#4 Express mongodb

poster
В этом уроке мы установим базу данных mongodb, подключим ее к проекту и порефакторим наши методы get и post, чтобы они работали с базой данных.
Понравилось? Поделитесь с друзьями!
Понравилось?
Поделитесь с друзьями!
Комментарии
Текст видео

Сегодня мы с вами разберем как подключать базу данных к нашему API.

В качестве базы данных мы будем с вами использовать mongodb. Почему именно ее? Это самая популярная из документ-ориентированных баз данных к ней есть много библиотек и она широко распространена.

Для установки mongodb на любой из платформ заходите на https://www.mongodb.com/download-center и качаете нужную вам версию.

Для macosx можно не качать напрямую а установить с помощью brew

brew install mongodb

После установки для пуска mongodb сервера достаточно написать в консоли mongod. Нужно помнить, что база данных запущена только пока этот процесс висит. Если вы остановите его нажам ctrl+c или command+c, то база работать не будет. Так что мы должны запускать mongod и нам express сервер в двух разных вкладках консоли.

Для работы с этой базой данных нам нужно установить пакет node-mongodb-native

npm install mongodb --save

Это нативный пакет для работы с nodejs.

Для начала нам необходимо импортировать MongoClient из пакета mongodb.

var MongoClient = require('mongodb').MongoClient;

и добавим переменную db в которой будет хранить ссылку на базу данных после подключения

var db;

и теперь внизу файла подконнектимся к базе данных, запишем в db ссылку на базу данных и запустим наш вебсервер

MongoClient.connect('mongodb://localhost:27017/myapi', function (err, database) {
  if (err) {
    return console.log(err);
  }
  db = database;
  app.listen(3012, function () {
    console.log('API app started');
  })
})

первым пераметром к connect указывается ссылка на нашу базу данных. Порт 27017 - это порт, где база данных поднимается по умолчанию. Мы можем указать любое название базы данных и она создастся автоматически.

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

Итак теперь доступ к базе у нас есть и давайте реализуем сохранение исполнителей в базу.

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

app.post('/artists', function (req, res) {
  var artist = {
    name: req.body.name
  };

  db.collection('artists').insert(artist, (err, result) => {
    if (err) {
      console.log(err);
      return res.sendStatus(500);
    }
    res.send(artist);
  })
})

Вызывая db.collection('artists') мы обращаемся к коллекции исполнителей. Если ее не существовало, то она будет создана автоматически. Дальше мы вызываем метод insert, который вставит артиста в базу данных. В коллбеке мы проверяем что у нас не было ошибки. Если была, то возвращаем статус 500. Если не было возвращаем артиста.

Давайте попробуем. Обратите внимание, что мы вернули нашего артиста, но в респонзе получили его уже с id. MongoClient автоматически генерирует уникальный id для записи.

Теперь давайте реализуем получение списка исполнителей.

app.get('/artists', function (req, res) {
  db.collection('artists').find().toArray(function (err, docs) {
    if (err) {
      console.log(err);
      return res.sendStatus(500);
    }
    res.send(docs);
  })
})

Здесь мы обращаемся к коллекции и говорим найди нам все документы в коллекции. Потом превращаем их в массив и возвращаем на рендер.

Теперь поиск отдельного документа в коллекции.

Для начала нам необходимо импортировать ObjectID из mongodb;

var ObjectID = require('mongodb').ObjectID
app.get('/artists/:id', function (req, res) {
  db.collection('artists').findOne({ _id: ObjectID(req.params.id) }, function (err, doc) {
    if (err) {
      console.log(err);
      return res.sendStatus(500);
    }
    res.send(doc);
  })
})

Тут мы используем метод findOne, которые вернет нам только один найденный документ. В качестве параметра он принимает обьект, где мы указываем, что хотим найти документ с id req.params.id. Тут есть нюанс, что на самом деле наши IDшники в базе это специальные ObjectID. Для нас это не важно пока, но чтобы найти документ нам нужно превратить нашу строку из параметров в ObjectID. В результате мы получим документ, который и возвращаем.

Итак в этом уроке мы установили базу данных, подключили ее к проекту и порефакторили наши методы get и post, чтобы они работали с базой данных.

Если у вас возникли какие-то вопросы или комментарии, пишите их прямо под этим видео.

Только зарегистрированные пользователи могут оставлять комментарии.  Войдите, пожалуйста.
Атхам Султон
7 месяцев назад
доброе утро. Можете простыми словами объяснить разницу между bodyParser.json(); bodyParser.urlencoded({ extended: true });
monsterlessons
7 месяцев назад
Доброе утро Это для того чтобы парсить formData: application/x-www-form-urlencoded app.use(bodyParser.urlencoded({ extended: false })) Это для json: application/json app.use(bodyParser.json())
Атхам Султон
7 месяцев назад
спасибо
dk
8 месяцев назад
для mongod 3+ можно так: // Connection URL const url = 'mongodb://localhost:27017'; // Database Name const dbName = 'myapi'; MongoClient.connect(url, function (err, client) { if (err) { return console.log(err); } db = client.db(dbName); app.listen(3012, function () { console.log('API app started'); }) });
sculptor
11 месяцев назад
У меня вылетает ошибка db.collection is not a function
monsterlessons
11 месяцев назад
В комментариях ниже уже писали - используйте версию mongodb 2.2.19, а не 3+
Анастасія Шевченко
4 месяцев назад
для версии 3+ должен быть не метод insert, a insertOne: db.collection('inserts').insertOne(artist, function (err, result) {...});
Daulet Syrymbetov
1год назад назад
У меня вылетает ошибка "Cannot read property 'collection' of null".
monsterlessons
1год назад назад
Скорее всего у вас проблема в версии mongodb, как писал Andrey Balab ниже. Попробуйте склонировать код урока и попробовать еще раз.
Andrey Balab
1год назад назад
друзья, в версии mongodb 3.0.0 какой то косяк, используйте версию автора: "mongodb": "^2.2.19" я столкнулся с тем что на POST запрос приходит ответ что db.collection('artists') is not a function
Знаковян Семён
1год назад назад
Ребят, кто подскажет, как вы, используя нативный драйвер под ноду для манго, который используется в данном курсе (mongodb) реализуете схему? То есть некий skeleton, который можно было б использовать. К примеру, у меня есть необходимость создавать статьи, и дату создания я б хотел брать как дату на момент создания запроса. При этом в запросе не передавать весь огромный объект со всеми свойствами статьи, а лишь те свойства которые динамичны. То есть второй вопрос - как можно задать некие свойства по умолчанию? Авторы похожих курсов забугром юзают mangoose, там есть schema, да с ней немало хлопот, но подход таки более систематизирован. Хочу услышать мнение автора курса по этому поводу, или тех кто работал с mangoose. Спасибо заранее!
monsterlessons
1год назад назад
В реальных приложениях я бы посоветовал использовать как меньше велосипедов. В этом курсе работа делалась с нативным драйвером, чтобы показать как можно полнее работу с mongo, без абстракций. Поэтому как ORM я бы предложил использовать mongoose или sequilize под node. Это 2 наиболее зрелых решения. Но, если вы реализуете проект в плане обучения, то написать модели самому отличный вариант. Например просто на ес6 классах class Post { constructor ({title}) { this.title = title this.createdAt = new Date } save () { db.table('posts').insert(this) } } const post = new Post({title: 'test'}) post.save()
vlad
1год назад назад
я не JavaScript Developer я только учусь :) - у меня пока нет реализованного сайта. 1. я раньше тренировался на PHP - Denwer и OpenServer и MySql. Т.е. запустил сервер (Denwer, OpenServer) и MySql вагоном запускался. Для релиза как я понял на хостер нужно было бы только БД залить и ВСЕ. MySql как я понял есть на большинстве хостеров. 2. с NODE и MONGODB (на ВИНДЕ) - нужно запустить mongod, затем mongo, затем node server. 3. Александр, если можно поясните, "на пальцах", как с NODE и с MONGODB сайт выкладывать на хостинг? как он будет работать? 4. У хостера не нужно будет спрашивать о поддержке NODE и MONGODB? 5. Webpack соберет "все"(NODE и MONGODB) в один файл bundle.js?
monsterlessons
1год назад назад
На пальцах вряд ли получится, там не 2 строчки написать. Поищите в интернете есть куча гайдов как залить node на сервер. В двух словах: нужен хостинг с поддержкой node либо просто нормальный vps. Там устанавливаете node и mongodb и запускаете. Webpack вам на сервере не нужен если у вас не реакт с сервер сайд рендерингом там.
vlad
1год назад назад
Robomongo: 1. вот такой вид у бесплатного релиза - http://prntscr.com/g89zpz 2. такой вид у профф версии - http://prntscr.com/g8a2v2. если Вы сообщите что проект не коммерческий то, как я понял, профф версия тоже будет бесплатной. Если так то это - Супер!!!!! 3. в профф версии - можно работать через SQL запросы - Супер!!!!!
vlad
1год назад назад
для ВИНДЫ - запуск mongodb (после установки mongodb): 1. перейти в папку - bin - в которую установили mongodb - c:\mongodb\bin\ 2. кликнуть mongod.exe 3. кликнуть кликнуть mongo.exe 4. в cmd ввести node server 5. отразится - API app started!!!!
vlad
1год назад назад
Вопрос. Для mongobd какой есть аналог phpMyAdmin для MySql? В сети я нашел материал про Robomongo - https://robomongo.org.
monsterlessons
1год назад назад
Не знаю. Я их не искал. Но то, что встроенного аналога phpMyAdmin нету это грустно. Попробуйте то, что вы написали.
vlad
1год назад назад
не пойму в чем причина бага у postman. вместо указанного name выдает null? Т.е. на странице http://localhost:3012/artists выодится массив типа { _id: "5980990787367224847295ae", name: null },
monsterlessons
1год назад назад
Проверьте передаете ли вы в хедера contentType: application/json. Похоже на то, что нода не может распарсить ваш body.
vlad
1год назад назад
в postman headers (который внизу) - там есть Content-Type →application/json; charset=utf-8 headers (который нижний) - там ничего нет
vlad
1год назад назад
то что руками ввел через командную строку - все ОК { _id: "5980de732992632b89d18501", фамилия: "иванов", имя: "иван" } что постмену не нравится?
monsterlessons
1год назад назад
Вот тут нужно указать хедер. https://prnt.sc/g3572d
vlad
1год назад назад
я и так делал. результата нет. на видео у Вас когда значится headers(1), то на строке ниже после binary следует "текст". у меня же как только я в хедер добавлял Content-Type application/json вместо "текст" выводится "JSON(application/json)"??? Если выбираю "обратно" "текст", то исчезает все то что указал в headers
vlad
1год назад назад
http://prntscr.com/g35lyj https://prnt.sc/g35m8n
monsterlessons
1год назад назад
Так сложно сказать. Нужно дебажить на конкретной машине. Попробуйте другой рест клиент для тестирования API, ведь проблема не в коде насколько я вижу.
Костя Вовкодав
1год назад назад
app.get('/artists/:id', function (req, res) { db.collection('artists').findOne({ _id: ObjectID(req.params.id) }, function (err, doc) { if (err) { console.log(err); return res.sendStatus(500); } res.send(doc); }) }) А как нам определить /artists/:id с бд? Например, пользователи добавили несколько постов. { "_id": "666", name: "black"} И теперь я хочу удалить этот пост с странички, но мне же нужно его ID знать. Я так понимаю, что при добавлении поста на UI нужно в параметры добавлять его id c базы?
monsterlessons
1год назад назад
Да конечно. К любой сущности на фронтенд нужно передавать id, по которому вы будете обращаться потом к API. То есть для удаления вы вначале передаете пост с id, name на фронтенд, а потом вызываете апи метод, который удалит пост по id.
Костя Вовкодав
1год назад назад
Спасибо за оперативность. Хорошие видео у Вас!!!
yugle7
2 лет назад
ошибка в тексте под видео - return не там стоит: return console.log(err) res.sendStatus(500);
monsterlessons
2 лет назад
Спасибо, исправил.
login2030
2 лет назад
На венде 7 версии не все так гладко с монгой как на маке, поэтому осмелюсь посоветовать вот этот туториал - https://www.youtube.com/watch?v=1uFY60CESlM
monsterlessons
2 лет назад
Спасибо большое за ссылку. Так как я винду не использую, то мне сложно сказать с какими проблемами там столкнутся люди.
blindeveloper
2 лет назад
привет, на это видео нет фильтра по категории nodejs
monsterlessons
2 лет назад
Спасибо за фидбек. Исправил.