Все, что вам нужно знать о создании базовых операций CRUD с помощью Express и MongoDB.
Эта статья - третья часть серии. Я рекомендую вам прочитать первую статью, чтобы понять цель этой серии, и вторую статью, чтобы узнать, как настроить рабочую среду разработки. Я также должен упомянуть, что создание API требует промежуточных навыков разработки, но это все равно не так уж и сложно. И да, мой стиль письма будет пояснительным и с мягкой терминологией.
В нашей последней статье мы завершили процесс создания среды разработки, давайте продолжим. В этой статье мы добавим одну важную функцию, которая будет создавать Cause CRUD. Это означает, что мы сможем создавать, извлекать, обновлять и удалять причины, которые являются основой нашего приложения. Итак, приступим. Мы создадим новый каталог для размещения наших кодов. В этом каталоге мы создадим три дополнительных каталога для наших моделей, контроллеров и маршрутов.
Слышали о MVC? Это аббревиатура от Model, View, Controller. Подробнее о MVC можно прочитать здесь. Мы будем строить с использованием архитектурного шаблона MVC, который в основном будет разбивать и разделять различные части нашего приложения, упорядочивая все в соответствии с функциями. Модели будут содержать коды базы данных, контроллер будет содержать логику приложения, которая будет обрабатывать запросы от клиента и выводить ответ, и, наконец, маршруты будут обрабатывать всю маршрутизацию. Каламбур предназначен. О, мы не будем реализовывать представление на этом этапе.
Сначала создайте новую ветку и перейдите к ней. Затем установите зависимости ниже и создайте наши каталоги. Сделайте это с помощью GitBash или любого интегрированного терминала git.
// create and checkout to a new branch git checkout -b ft-CRUD // npm install the needed dependencies npm install body-parser morgan mongoose --save // create new directory mkdir server // change to server directory cd server // add three more directories mkdir controllers models routes
Настроить точку входа в приложение
Три только что установленные зависимости будут делать следующее. Body-parser извлечет часть тела входящего запроса и предоставит его в req.body, а также включит обработку HTTP-запросов, таких как POST, PUT, PATCH и DELETE. Morgan - это промежуточное программное обеспечение, которое обрабатывает и регистрирует записи запросов и ответы на консоль, и, наконец, mongoose - это средство отображения объектных документов, обычно используемое для MongoDB.
Затем мы сделаем эти зависимости доступными для нашего приложения, настроив их в точке входа приложения. Вот код для этого.
// import dependencies import express from 'express'; import bodyParser from 'body-parser'; import mongoose from 'mongoose'; import logger from 'morgan'; // set up dependencies const app = express(); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false }); app.use(logger('dev')); // set up mongoose mongoose.connect('mongodb://localhost/projectsupport') .then(()=> { console.log('Database connected'); }) .catch((error)=> { console.log('Error connecting to database'); }); // set up port const port = 5035; // set up route app.get('/', (req, res) => { res.status(200).json({ message: 'Welcome to Project Support', }); }); app.listen(port, () => { console.log(`Our server is running on port ${port}`); });
Первые двенадцать строк в основном импортируют и настраивают зависимости, делая их доступными в нашем файле app.js. Следующие семь строк после этого в основном используют обещание JavaScript для настройки мангуста и обработки любой потенциальной ошибки. Остальное мы уже определили в нашей предыдущей статье. Я должен упомянуть, что строка 14 не должна быть открытой, передовая практика требует, чтобы мы определяли ее в файле .env, но мы будем работать с этим сейчас и вернемся к нему позже.
Для настройки базы данных на вашем компьютере должна быть установлена MongoDB. Если у вас уже установлен MongoDB на вашем компьютере, пропустите это, в противном случае используйте this. Более простое руководство можно найти здесь. После установки MongoDB вам нужно будет запустить его. Это довольно просто. Мне нравится использовать для этого командную строку по умолчанию. Разобравшись с этим, давайте запустим наш сервер.
// start mongoDB using CMD // Locate mongodb and open directory which is most likely in C:/ cd mongodb // change directories to bin cd bin // start mongod mongod
Давайте запустим наш сервер с помощью нашего терминала git
npm run start:dev
Создание моделей
Далее мы создадим нашу модель. Давайте начнем с простого приложения, которое требует, чтобы мы только заполняли заголовок и описание, когда мы хотим создать причину. Созданная нами причина будет храниться в нашей MongoDB и предоставляться клиенту по запросу. Наша первая модель будет cause.js, и вот код для этого. Это будет набрано с помощью GitBash или, лучше, интегрированного терминала git в VSCode.
// create a cause.js in our models directory touch server/models/cause.js // open cause.js start server/models/cause.js
А теперь собственно код. Это будет в файле cause.js
import mongoose from 'mongoose; mongoose.Promise = global.Promise; const causeSchema = new mongoose.Schema({ _id: mongoose.Schema.Types.ObjectId, title: { type: String, required: true, }, description: { type: String, required: true, }, }); export default mongoose.model('Cause', causeSchema);
Это довольно просто. Мы импортировали мангуста и создали схему для хранения в базе данных. Далее мы определим логику, которая действительно создает причину. Сделаем это в контроллере.
Создание контроллера
Точно так же, как мы создали файл cause.js в каталоге моделей, вы должны создать файл cause.js в каталоге контроллеров и ввести в него приведенный ниже код.
import mongoose from 'mongoose'; import Cause from '../models/cause'; // create new cause export function createCause(req, res) { const cause = new Cause({ _id: mongoose.Types.ObjectId(), title: req.body.title, description: req.body.description, }); return cause .save() .then((newCause) => { return res.status(201).json({ success: true, message: 'New cause created successfully', Cause: newCause, }); }) .catch((error) => { res.status(500).json({ success: false, message: 'Server error. Please try again.', error: error.message, }); }); }
Итак, похоже, здесь происходит много чего, но не волнуйтесь, это несложно. Строки 1 и 2 в основном импортируют мангуста и нашу модель причины. Помните, что мы экспортировали нашу причинную модель в последней строке при создании причинной модели. Остальной код в основном создает новую причину. Вот как это работает. Строка 6–10 создает причину, сначала определяя, как будут получены значения, а затем сопоставляя это с ключами. Строки 12–27 возвращает обещание и обрабатывает любую потенциальную ошибку с помощью метода .catch. Если все пойдет хорошо, запустится строка 13–20 и сохранит созданную причину в базе данных, а строка 16–18 будет отправлена в качестве ответа клиенту. В случае любой ошибки будет запущена строка 21–27, а строка 23–25 будет отправлена в качестве ответа клиенту.
Создание маршрутов
Мы уже сделали сложную часть, теперь мы просто определяем маршрут и открываем его нашей точке входа. Итак, приступим. Начните с создания main.js в каталоге маршрутизаторов, как мы это делали для моделей и контроллеров. Как только это будет сделано, введите приведенный ниже код.
import express from 'express'; import { createCause } from '../controllers/cause'; const router = express.Router(); router.post('/causes', createCause); export default router;
Мы так много сделали, и пришло время проверить то, что мы написали. О, давайте добавим две строки к нашей точке входа. Это экспортирует наши маршруты и покажет их в нашей точке входа. Из приведенных ниже фрагментов кода строка 4 импортирует наши маршруты, а строка 9 устанавливает их с префиксом / api.
// call in the installed dependencies ... import logger from 'morgan'; import mainRoutes from './server/routes/main'; ... // set up route app.use('/api/', mainRoutes); ...
С Postman тестирование на самом деле доставляет удовольствие. Запустите Postman и давайте проверим, работает ли наше приложение.
Это круто. Мы только что создали новую причину, и она сохранена в MongoDB. Это было не так уж сложно, правда? Теперь нам нужно будет написать логику для извлечения этой причины, обновления причины и удаления причины. Наша модель уже определена, поэтому мы не будем делать это снова, логика будет содержаться в нашем контроллере, и мы, наконец, добавим конечную точку в наш маршрутизатор. Итак, приступим.
В каталоге контроллера откройте файл cause.js и введите приведенный ниже код после функции createCause. О, это должно быть до линии экспорта.
// Get all causes export function getAllCause({ Cause.find() .select('_id title description') .then((allCause) => { return res.status(200).json({ success: true, message: 'A list of all causes', Cause: allCause, }); }) .catch((err) => { res.status(500).json({ success: false, message: 'Server error. Please try again.', error: err.message, }); }); }
Затем мы импортируем это в наш каталог маршрутов. Откройте main.js в нашем каталоге маршрутов и введите приведенный ниже код.
import { createCause, getAllCause } from '../controllers/main'; ... router.post('/events', createCause); router.get('/events', getAllCause); export default router;
Как видно из Postman, мы можем получить все причины и отправить ответ JSON клиенту. Нам еще предстоит разработать еще пару конечных точек, так что приступим. В нашем каталоге контроллеров давайте добавим коды для получения единственной причины. Если вы понаблюдаете, то заметите, что уникальность каждой причины - ее идентификатор. Если вы также заметили, мы не определяли идентификатор сами, мы позволили мангусту позаботиться об этом. Преимущество идентификатора, сгенерированного мангустом, включает в себя глобально уникальный идентификатор во всех практических целях. Подробнее об идентификаторе мангуста можно прочитать здесь.
Этот уникальный идентификатор упрощает доступ к отдельным причинам. В основном то, что мы будем делать, просматривать базу данных и находить по Id. Напишем для этого несколько кодов. Сделайте это после getAllCause.
// get single cause export function getSingleCause(req, res) { const id = req.params.causeId; Cause.findById(id) .then((singleCause) => { res.status(200).json({ success: true, message: `More on ${singleCause.title}`, Cause: singleCause, }); }) .catch((err) => { res.status(500).json({ success: false, message: 'This cause does not exist', error: err.message, }); }); }
Затем мы добавляем эту конечную точку в наш main.js, поднимаемся туда и добавляем код ниже:
... import { createCause, getAllCause, getSingleCause } from '..controllers/cause'; ... router.get('/cause', getAllCause); router.get('/cause/:causeId', getSingleCause); ...
Давайте проверим это с помощью Postman ... Просто скопируйте идентификатор причины, добавьте его в URL и отправьте.
Затем мы добавим как обновление, так и удаление конечных точек. Опять же, мы добавим это в наш контроллер. Поговорим немного об обновлении. Для этого доступны два метода HTTP: PUT и PATCH, которые иногда используются как взаимозаменяемые в некоторых руководствах. Однако на самом деле оба они не одно и то же. PUT в основном позволяет полностью заменить документ, а PATCH позволяет частичную замену документа. В этой статье мы будем использовать PATCH.
Давай уже займемся этим. Чтобы понять, как работает оператор $ set в MongoDB, перейдите по этой ссылке.
// update cause export function updateCause(req, res) { const id = req.params.causeId; const updateObject = req.body; Cause.update({ _id:id }, { $set:updateObject }) .exec() .then(() => { res.status(200).json({ success: true, message: 'Cause is updated', updateCause: updateObject, }); }) .catch((err) => { res.status(500).json({ success: false, message: 'Server error. Please try again.' }); }); }
Затем мы перейдем к нашему main.js в каталоге маршрута и определим нашу конечную точку обновления.
... import { createCause, getAllCause, getSingleCause, updateCause } from '../controllers/cause'; ... router.get('/causes/:causeId', getSingleCause); router.patch('/causes/:causeId', updateCause); ...
После этого мы протестируем с помощью почтальона, чтобы проверить его работу.
Ура! Мы почти закончили. Последняя конечная точка, над которой нужно работать, и это конечная точка удаления. Давай и этим займемся. Введите код ниже после причины обновления.
// delete a cause export function deleteCause(req, res) { const id = req.params.causeId; Cause.findByIdAndRemove(id) .exec() .then(()=> res.status(204).json({ success: true, })) .catch((err) => res.status(500).json({ success: false, })); }
Как вы уже должны знать, нам нужно будет обновить его до нашего main.js в каталоге маршрута. Давай сделаем это прямо сейчас. Откройте main.js и введите приведенный ниже код.
... import { createCause, getAllCause, getSingleCause, updateCause, deleteCause } from '../controllers/main'; ... router.patch('/cause/:causeId', updateCause); router.delete('/cause/:causeId', deleteCause); ...
Давайте проверим это, чтобы убедиться, что это действительно работает.
Потрясающие. Мы успешно удалили эту причину. Мы можем решить вывести ответ клиенту, но для этого нам нужно будет заменить код состояния 204 на 200 и ввести сообщение. Теперь давайте проверим, чтобы убедиться, что эта причина удалена, попытавшись получить ее содержание. Опять почтальон.
Ура! Мы успешно написали и протестировали, чтобы показать, что он работает, коды для создания, извлечения, обновления и удаления причины. На этом мы подошли к концу статьи. И последнее, нам нужно будет отправить наши коды в наш репозиторий.
// to see a list of all changes git status // to add all changes to git git add . // to commit all changes to git git commit -m 'completed the cause crud operations' // to push changes to remote repository git push origin ft-crud
Если вам нужно увидеть полные коды и сравнить с тем, что у вас есть, вот ссылка на репозиторий GitHub, ProjectSupport.
В нашей следующей статье мы добавим регистрацию пользователей и вход в систему к тому, что мы уже сделали, и да, аутентификация будет выполняться с использованием JWT. Мы также будем защищать конечные точки, такие как причины создания, обновления и удаления, доступные только пользователям с аутентифицированным токеном.
Чтобы прочитать о развертывании в mLab и Heroku, нажмите здесь.
Если вам понравилась эта статья или у вас возникли проблемы с внедрением кодов на вашей стороне, дайте мне знать в разделе комментариев, и я буду ждать. И да, я хотел бы знать, что ваши коды тоже работали, как ожидалось.