#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, чтобы они работали с базой данных.

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

Только зарегистрированные пользователи могут оставлять комментарии.  Войдите, пожалуйста.
Атхам Султон
11 месяцев назад
доброе утро. Можете простыми словами объяснить разницу между bodyParser.json(); bodyParser.urlencoded({ extended: true });
monsterlessons
11 месяцев назад
Доброе утро Это для того чтобы парсить formData: application/x-www-form-urlencoded app.use(bodyParser.urlencoded({ extended: false })) Это для json: application/json app.use(bodyParser.json())
Атхам Султон
11 месяцев назад
спасибо
dk
1год назад назад
для 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
1год назад назад
У меня вылетает ошибка db.collection is not a function
monsterlessons
1год назад назад
В комментариях ниже уже писали - используйте версию mongodb 2.2.19, а не 3+
Анастасія Шевченко
8 месяцев назад
для версии 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
Знаковян Семён
2 лет назад
Ребят, кто подскажет, как вы, используя нативный драйвер под ноду для манго, который используется в данном курсе (mongodb) реализуете схему? То есть некий skeleton, который можно было б использовать. К примеру, у меня есть необходимость создавать статьи, и дату создания я б хотел брать как дату на момент создания запроса. При этом в запросе не передавать весь огромный объект со всеми свойствами статьи, а лишь те свойства которые динамичны. То есть второй вопрос - как можно задать некие свойства по умолчанию? Авторы похожих курсов забугром юзают mangoose, там есть schema, да с ней немало хлопот, но подход таки более систематизирован. Хочу услышать мнение автора курса по этому поводу, или тех кто работал с mangoose. Спасибо заранее!
monsterlessons
2 лет назад
В реальных приложениях я бы посоветовал использовать как меньше велосипедов. В этом курсе работа делалась с нативным драйвером, чтобы показать как можно полнее работу с 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
2 лет назад
я не 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
2 лет назад
На пальцах вряд ли получится, там не 2 строчки написать. Поищите в интернете есть куча гайдов как залить node на сервер. В двух словах: нужен хостинг с поддержкой node либо просто нормальный vps. Там устанавливаете node и mongodb и запускаете. Webpack вам на сервере не нужен если у вас не реакт с сервер сайд рендерингом там.
vlad
2 лет назад
Robomongo: 1. вот такой вид у бесплатного релиза - http://prntscr.com/g89zpz 2. такой вид у профф версии - http://prntscr.com/g8a2v2. если Вы сообщите что проект не коммерческий то, как я понял, профф версия тоже будет бесплатной. Если так то это - Супер!!!!! 3. в профф версии - можно работать через SQL запросы - Супер!!!!!
vlad
2 лет назад
для ВИНДЫ - запуск mongodb (после установки mongodb): 1. перейти в папку - bin - в которую установили mongodb - c:\mongodb\bin\ 2. кликнуть mongod.exe 3. кликнуть кликнуть mongo.exe 4. в cmd ввести node server 5. отразится - API app started!!!!
vlad
2 лет назад
Вопрос. Для mongobd какой есть аналог phpMyAdmin для MySql? В сети я нашел материал про Robomongo - https://robomongo.org.
monsterlessons
2 лет назад
Не знаю. Я их не искал. Но то, что встроенного аналога phpMyAdmin нету это грустно. Попробуйте то, что вы написали.
vlad
2 лет назад
не пойму в чем причина бага у postman. вместо указанного name выдает null? Т.е. на странице http://localhost:3012/artists выодится массив типа { _id: "5980990787367224847295ae", name: null },
monsterlessons
2 лет назад
Проверьте передаете ли вы в хедера contentType: application/json. Похоже на то, что нода не может распарсить ваш body.
vlad
2 лет назад
в postman headers (который внизу) - там есть Content-Type →application/json; charset=utf-8 headers (который нижний) - там ничего нет
vlad
2 лет назад
то что руками ввел через командную строку - все ОК { _id: "5980de732992632b89d18501", фамилия: "иванов", имя: "иван" } что постмену не нравится?
monsterlessons
2 лет назад
Вот тут нужно указать хедер. https://prnt.sc/g3572d
vlad
2 лет назад
я и так делал. результата нет. на видео у Вас когда значится headers(1), то на строке ниже после binary следует "текст". у меня же как только я в хедер добавлял Content-Type application/json вместо "текст" выводится "JSON(application/json)"??? Если выбираю "обратно" "текст", то исчезает все то что указал в headers
vlad
2 лет назад
http://prntscr.com/g35lyj https://prnt.sc/g35m8n
monsterlessons
2 лет назад
Так сложно сказать. Нужно дебажить на конкретной машине. Попробуйте другой рест клиент для тестирования API, ведь проблема не в коде насколько я вижу.
Костя Вовкодав
2 лет назад
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
2 лет назад
Да конечно. К любой сущности на фронтенд нужно передавать id, по которому вы будете обращаться потом к API. То есть для удаления вы вначале передаете пост с id, name на фронтенд, а потом вызываете апи метод, который удалит пост по id.
Костя Вовкодав
2 лет назад
Спасибо за оперативность. Хорошие видео у Вас!!!
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 лет назад
Спасибо за фидбек. Исправил.