Автор оригинала: Rahman Fadhil.
Этот пост изначально опубликован здесь .
В этом руководстве построено вам построить спокойную API с Node.js, Express и Mongoose с функциональными возможностями CruD. Я ожидаю, что у вас есть основные знания Node.js и JavaScript. Если вы делаете, вы добруетесь!
Предпосылки
Эти программы необходимо сначала установить на вашем компьютере:
Начиная
Единственное, что нам нужно начать с этого проекта, это пустая папка с пакетом NPM инициализирована. Итак, давайте создадим один!
$ mkdir learn-express $ cd learn-express $ npm init -y
Теперь давайте устанавливаем некоторые полезные пакеты.
$ npm install express mongoose body-parser
Здесь мы устанавливаем Экспресс Для нашей веб-структуры мангуст Взаимодействовать с нашей базой данных MongoDB и Тело-парсер разбирать нашу просьбу организма.
Я также опубликовал исходный код всего проекта на моем Github. Идите вперед и клонируйте это на свой компьютер.
$ git clone https://github.com/rahmanfadhil/learn-express-mongoose.git
Базовый экспресс-сервер
Теперь мы можем начать создавать index.js
и создать простой экспресс-сервер.
// index.js const express = require("express") const app = express() app.listen(5000, () => { console.log("Server has started!") })
Сначала мы импортируем наши Экспресс
Пакет, который мы только что установили. Затем создайте новый экземпляр Express и поместите его в приложение
Переменная. Это приложение
Переменная Давайте сделаем все, что нам нужно настроить на нашу API для отдыха, например, регистрацию наших маршрутов, устанавливая необходимые подразнения и многое другое.
Попробуйте запустить наш сервер, запустив эту команду ниже.
$ node index.js Server has started!
В качестве альтернативы, мы можем настроить новый сценарий NPM, чтобы сделать наш рабочий процесс гораздо более проще.
{ "scripts": { "start": "node index.js" } }
Затем мы можем запустить наш сервер, выполнив NPM начать
Отказ
$ npm start Server has started!
Настройка мангусты
Mongoose является наиболее предпочтительным оболочкой MongoDB для Node.js. Это позволяет нам с легкостью взаимодействовать с базой данных MongoDB. Мы можем начать подключить наш сервер в нашу базу данных MongoDB.
// index.js const express = require("express") const mongoose = require("mongoose") mongoose .connect("mongodb://localhost:27017/acmedb", { useNewUrlParser: true }) .then(() => { const app = express() app.listen(5000, () => { console.log("Server has started!") }) })
Здесь мы импортируем мангуст
Пакет и используйте его для подключения к нашей базе данных под названием acmedb
, но вы можете назвать это все, что вы хотите. Если вы не создали эту базу данных, не волнуйтесь, Mongoose создаст его для YA.
Метод Connect возвращает обещание, поэтому мы можем дождаться, пока он не будет не решен, а запустить наш экспресс-сервер.
Запустите сервер снова и убедитесь, что нет ошибки.
$ npm start Server has started!
Теперь мы успешно подключаем наш сервер с базой данных, теперь пришло время создавать нашу первую модель.
Модель мангусты
В мире NoSQL каждые отдельные данные хранятся внутри одного документа. И несколько документов с одним и тем же типом могут быть собраны внутри коллекции.
Модель – это класс, который позволяет нам взаимодействовать с определенной коллекцией базы данных.
Определение модели также требует от нас определить схему. Схема в основном рассказывает модели, как наш документ должен выглядеть так. Несмотря на то, что в мире NoSQL схема документов гибкая, Mongoose помогает нам сохранить наши данные более последовательными.
Допустим, у нас есть API блога. Итак, мы, очевидно, будем иметь Пост
модель. И эта модель имеет схему, которая содержит поля, которые могут быть добавлены в один документ. Для этого примера у нас просто будет Название
и Содержание
поле.
Итак, давайте добавим новую папку в нашем проекте под названием модели
и создать файл под названием Post.js
внутри него.
// models/Post.js const mongoose = require("mongoose") const schema = mongoose.Schema({ title: String, content: String }) module.exports = mongoose.model("Post", schema)
Здесь мы строим схему mongoose.schema
и определите поля, а также типы данных. Затем мы создаем новую модель, используя Mongoose.model
на основе схемы, которую мы только что создали.
Получить все сообщения
Здесь мы можем создать новый файл под названием Маршруты.js
который будет содержит наши экспресс-маршруты.
// routes.js const express = require("express") const router = express.Router() module.exports = router
Нам также нужно импортировать Экспресс
Но на этот раз мы хотим использовать Express.Rooter
Отказ Это позволяет нам зарегистрировать маршруты и использовать его в нашем приложении (в | index.js ).
Теперь мы готовы создать наш первый маршрут в Express, которые на самом деле что-то делают!
Давайте создадим маршрут, который может получить список существующих постов.
// index.js const express = require("express") const Post = require("./models/Post") // new const router = express.Router() // Get all posts router.get("/posts", async (req, res) => { const posts = await Post.find() res.send(posts) }) module.exports = router
Здесь мы импортируем Пост
Модель и создать новый Получить
Маршрут с Router.get
метод. Этот метод примет конечную точку маршрута, а обработчик маршрута для определения того, какие данные следует отправлять клиенту. В этом случае мы собираемся получить все наши посты с Найти
из нашей модели и отправьте результат с res.send
метод.
Поскольку для получения документов из базы данных асинхронные, нам нужно использовать ждать
ждать, пока операция не закончится. Итак, не забудьте пометить свою функцию как async
Отказ Затем после того, как данные полностью извлечены, мы можем отправить его клиенту.
Теперь мы можем установить наши маршруты в нашу index.js
Отказ
// index.js const express = require("express") const mongoose = require("mongoose") const routes = require("./routes") // new mongoose .connect("mongodb://localhost:27017/acmedb", { useNewUrlParser: true }) .then(() => { const app = express() app.use("/api", routes) // new app.listen(5000, () => { console.log("Server has started!") }) })
Во-первых, мы импортируем ./routes.js
файл, чтобы получить все маршруты и зарегистрируйте его с помощью app.use
Способ с префиксом /API
Итак, все наши посты могут быть доступны в /API/Посты
Отказ
Попробуйте запустить наш сервер и получить /API/Посты
Давайте посмотрим, что мы получили.
$ curl http://localhost:5000/api/posts []
Теперь мы получили пустой массив с нашего сервера. Это потому, что мы еще не создавали ни одного поста. Итак, почему бы не создать один?
Создать пост
Чтобы создать пост, нам нужно принять Пост
Запросы от /API/Посты
Отказ
// routes.js router.post("/posts", async (req, res) => { const post = new Post({ title: req.body.title, content: req.body.content }) await post.save() res.send(post) })
Здесь мы создаем новый Пост
Объект и заполнить поля из req .body
имущество. req
Объект содержит данные запроса клиента, а тело является одним из них.
Тогда нам также нужно сохранить нашу запись с Сохранить
метод. Сохранение данных также асинхронно, поэтому нам нужно использовать синтаксис Async/en a ждать.
По умолчанию Express не знает, как прочитать тело запроса. Вот почему нам нужно использовать Тело-парсер
Разбираться в тело нашего запроса в объект JavaScript.
// index.js const express = require("express") const mongoose = require("mongoose") const routes = require("./routes") const bodyParser = require("body-parser") mongoose .connect("mongodb://localhost:27017/acmedb", { useNewUrlParser: true }) .then(() => { const app = express() app.use(bodyParser.json()) app.use("/api", routes) app.listen(5000, () => { console.log("Server has started!") }) })
Здесь мы используем Тело-парсер
Библиотека как промежуточное программное обеспечение для анализа тела JSON, чтобы мы могли получить доступ к нему через req .body
в нашем обработке маршрута.
Давайте проверим функцию Create Post, которую мы только что создали!
$ curl http://localhost:5000/api/posts \ -X POST \ -H "Content-Type: application/json" \ -d '{"title":"Post 1", "content":"Lorem ipsum"}' { "_v": 0, "_id":, "title": "Post 1", "content": "Lorem ipsum" }
Вы также можете проверить это с Почтальон также.
Получить индивидуальный пост
Чтобы схватить отдельный пост, нам нужно создать новый маршрут с Получить
метод.
// routes.js router.get("/posts/:id", async (req, res) => { const post = await Post.findOne({ _id: req.params.id }) res.send(post) })
Здесь мы регистрируем новый маршрут с конечной точкой /посты/: ID
Отказ Это называется параметром URL, он позволяет нам захватить ID
нашего поста на нашем обращении маршрута. Потому что каждый документ, который мы хранили в нашей базе данных, имеет свой собственный идентификатор Uniqe под названием Объект
Отказ И мы можем найти его, используя Findone
Способ и пройти идентификатор от req.params
объект.
Cool, теперь попробуйте получить один пост блога с нашим HTTP-клиентом.
$ curl http://localhost:5000/api/posts/{ "_id": , "title": "Post 1", "content": "Lorem ipsum" }
Похоже, его работа, но есть одна вещь, хотя.
Если мы к этому маршруту и пропустите неправильную ObjectID, наш сервер разбивается. И причина, по которой его не работает, заключается в том, что когда мы получим один пост с помощью ObjectID, который не существует, отклоняет обещание, и наше приложение перестает работать.
Чтобы предотвратить это, мы можем обернуть наш код с помощью блока TRY/CALL, чтобы мы могли отправить пользовательскую ошибку всякий раз, когда клиент запрашивает данные, которые не существуют.
// routes.js router.get("/posts/:id", async (req, res) => { try { const post = await Post.findOne({ _id: req.params.id }) res.send(post) } catch { res.status(404) res.send({ error: "Post doesn't exist!" }) } })
Теперь, если мы попытаемся получить пост, который не существует, наш сервер все еще ведет себя так, как должно быть.
$ curl http://localhost:5000/api/posts/{ "error": "Post doesn't exist!" }
Обновить пост
Обычно предпочтительный метод HTTP для выполнения операции обновления в одну запись является Патч
Отказ Итак, давайте создадим один!
// routes.js router.patch("/posts/:id", async (req, res) => { try { const post = await Post.findOne({ _id: req.params.id }) if (req.body.title) { post.title = req.body.title } if (req.body.content) { post.content = req.body.content } await post.save() res.send(post) } catch { res.status(404) res.send({ error: "Post doesn't exist!" }) } })
Наш обновление почтовый маршрут относительно похоже на маршрут «Получить один пост». Мы ищем пост, основываясь на ID и выбросить пользовательскую ошибку, если пост не существует. Но на этот раз мы также обновляем каждое поле объекта Post, заполнив его с данными, предоставляемыми клиентом внутри req .body
Отказ
Мы также хотим сохранить наш почтовый объект с Сохранить
Способ и отправьте данные обновления почтовых данных клиенту.
Теперь мы можем запустить Патч
Метод нашему /API/Посты/
конечная точка.
$ curl http://localhost:5000/api/posts/\ -X PATCH \ -H "Content-Type: application/json" \ -d '{"title":"Updated Post", "content":"Updated post content"}' { "__v": 0, "_id": , "title": "Updated Post" "content": "Updated Post content", }
Удалить пост
Наконец, наш последний шаг – закончить функцию CRUD, добавив функцию удаления.
// routes.js router.delete("/posts/:id", async (req, res) => { try { await Post.deleteOne({ _id: req.params.id }) res.status(204).send() } catch { res.status(404) res.send({ error: "Post doesn't exist!" }) } })
В маршруте Delete Post мы в основном просто запустите операцию удаления непосредственно в базу данных с помощью DELETEONE
Способ и передайте идентификатор документа. И мы ничего не вернем к пользователю.
$ curl http://localhost:5000/posts/-X DELETE -I HTTP/1.0 204 NO CONTENT ...