The MEAN (MongoDB, Express, Angular, Node.js) stack is a popular one. It represents the opportunity to work with JavaScript on both sides of the application (Backend & Frontend).
MEAN(MongoDB,Express,Angular,Node.js)堆栈是一种流行的堆栈。 它代表了在应用程序的两侧(后端和前端)使用JavaScript的机会。
During this lecture I’ll show you how to add a MongoDB database to the project created previously (Node.js + Express + Angular stack).
在本讲座中,我将向您展示如何向以前创建的项目( Node.js + Express + Angular stack )中添加MongoDB数据库。
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/59a44e57db460d435c92704158eb9159.png)
1.一些定义: (1. Some definitions:)
MongoDB: is a cross-platform document-oriented database. Defined as a NoSQL and uses JSON-like documents with optional schemas.
MongoDB :是一个跨平台的面向文档的数据库。 定义为NoSQL,并使用具有可选模式的类似JSON的文档。
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/07e4bee412f3161e75e7c90b1ed63eca.gif)
Anyway the MongoBD definition, the functionalities and why you should use it rather than other databases are not the purpose of this lecture (maybe another time, or never 🙄).
无论如何,MongoBD的定义,功能以及为什么要使用它而不是其他数据库都不是本讲座的目的(也许是另一回事,或从不🙄)。
2.将MongoDB添加到我们的堆栈中: (2. Adding MongoDB to our stack:)
Let’s take a look to our server file from the previous lecture:
让我们来看看上一堂课的服务器文件:
// Use Express
var express = require("express");
// Use body-parser
var bodyParser = require("body-parser");
// Create new instance of the express server
var app = express();
// Define the JSON parser as a default way
// to consume and produce data through the
// exposed APIs
app.use(bodyParser.json());
// Create link to Angular build directory
// The `ng build` command will save the result
// under the `dist` folder.
var distDir = __dirname + "/dist/";
app.use(express.static(distDir));
// Init the server
var server = app.listen(process.env.PORT || 8080, function () {
var port = server.address().port;
console.log("App now running on port", port);
});
/* "/api/status"
* GET: Get server status
* PS: it's just an example, not mandatory
*/
app.get("/api/status", function (req, res) {
res.status(200).json({ status: "UP" });
});
This server provides only one REST service /api/status
returning a static value "UP”
.
该服务器仅提供一个REST服务/api/status
返回静态值"UP”
。
The idea will be to manage resource(s) using the CRUD (Create, Read, Update and Delete) functions of the persistence strategy.
这个想法将使用CRUD(C reate,R EAD,U PDATE和d elete)的持久性策略的函数来管理资源(多个)。
To add MongoDB to our server:
要将MongoDB添加到我们的服务器:
Download MongoDB: https://docs.mongodb.com/manual/tutorial/
下载MongoDB: https : //docs.mongodb.com/manual/tutorial/
Run the following command on the project root directory in order to add the MongoDB dependency
npm install mongodb --save
在项目根目录上运行以下命令,以添加MongoDB依赖项
npm install mongodb --save
The following server.js
file version contains the MongoDB connection:
下面的server.js
文件版本包含MongoDB连接:
// Use Express
var express = require("express");
// Use body-parser
var bodyParser = require("body-parser");
// Use MongoDB
var mongodb = require("mongodb");
var ObjectID = mongodb.ObjectID;
// The database variable
var database;
// The products collection
var PRODUCTS_COLLECTION = "products";
// Create new instance of the express server
var app = express();
// Define the JSON parser as a default way
// to consume and produce data through the
// exposed APIs
app.use(bodyParser.json());
// Create link to Angular build directory
// The `ng build` command will save the result
// under the `dist` folder.
var distDir = __dirname + "/dist/";
app.use(express.static(distDir));
// Local database URI.
const LOCAL_DATABASE = "mongodb://localhost:27017/app";
// Local port.
const LOCAL_PORT = 8080;
// Init the server
mongodb.MongoClient.connect(process.env.MONGODB_URI || LOCAL_DATABASE,
{
useUnifiedTopology: true,
useNewUrlParser: true,
}, function (error, client) {
// Check if there are any problems with the connection to MongoDB database.
if (error) {
console.log(error);
process.exit(1);
}
// Save database object from the callback for reuse.
database = client.db();
console.log("Database connection done.");
// Initialize the app.
var server = app.listen(process.env.PORT || LOCAL_PORT, function () {
var port = server.address().port;
console.log("App now running on port", port);
});
});
/* "/api/status"
* GET: Get server status
* PS: it's just an example, not mandatory
*/
app.get("/api/status", function (req, res) {
res.status(200).json({ status: "UP" });
});
// Errors handler.
function manageError(res, reason, message, code) {
console.log("Error: " + reason);
res.status(code || 500).json({ "error": message });
}
The code is commented (don’t hesitate to tell me if I missed some information) but let’s take a look to some key points:
该代码已注释(如果我错过了一些信息,请不要犹豫告诉我),但让我们看一下一些关键点:
We use the new dependency integrated with
var mongodb = require("mongodb");
我们使用与
var mongodb = require("mongodb");
集成在一起的新依赖项var mongodb = require("mongodb");
We will use the ObjectID object managing identifiers for our objects (represents a concatenation of 4-byte timestamp value + 5-byte random value + 3-byte incrementing counter, initialized to a random value) with
var ObjectID = mongodb.ObjectID;
我们将为对象使用ObjectID对象管理标识符(表示4字节时间戳值+ 5字节随机值+ 3字节递增计数器的串联,初始化为随机值),其中
var ObjectID = mongodb.ObjectID;
We will manage some products during this lecture, so the idea with
var PRODUCTS_COLLECTION = “products”;
is just preparing a collection to store them在本讲座中,我们将管理一些产品,因此
var PRODUCTS_COLLECTION = “products”;
只是准备一个收集来存储它们
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/49cb60e1a5dcfeaaca706e2915b63658.gif)
Locally, the MongoDB database is running on port and URI represented with the two values
LOCAL_PORT
andLOCAL_DATABASE
在本地,MongoDB数据库在端口和URI上运行,并用两个值
LOCAL_PORT
和LOCAL_DATABASE
- Then we save the database object from the callback and starts the server 然后我们从回调中保存数据库对象并启动服务器
3.使用数据库: (3. Use the database:)
As I said, we will manage some products. Each product contains three mandatory values {_id: string, name: string, brand: string}.
正如我所说,我们将管理一些产品。 每个产品均包含三个必填值{_id: string, name: string, brand: string}.
To do that, we need to create new REST services:
为此,我们需要创建新的REST服务:
/api/products
with the GET verb to get all products./api/products
使用GET动词获取所有产品。/api/products
with the POST verb to create a product./api/products
用POST动词创建产品。/api/products/:id
with the DELETE verb to delete a product using the identifier./api/products/:id
与DELETE动词一起使用标识符来删除产品。
// Use Express
var express = require("express");
// Use body-parser
var bodyParser = require("body-parser");
// Use MongoDB
var mongodb = require("mongodb");
var ObjectID = mongodb.ObjectID;
// The database variable
var database;
// The products collection
var PRODUCTS_COLLECTION = "products";
// Create new instance of the express server
var app = express();
// Define the JSON parser as a default way
// to consume and produce data through the
// exposed APIs
app.use(bodyParser.json());
// Create link to Angular build directory
// The `ng build` command will save the result
// under the `dist` folder.
var distDir = __dirname + "/dist/";
app.use(express.static(distDir));
// Local database URI.
const LOCAL_DATABASE = "mongodb://localhost:27017/app";
// Local port.
const LOCAL_PORT = 8080;
// Init the server
mongodb.MongoClient.connect(process.env.MONGODB_URI || LOCAL_DATABASE,
{
useUnifiedTopology: true,
useNewUrlParser: true,
}, function (error, client) {
// Check if there are any problems with the connection to MongoDB database.
if (error) {
console.log(error);
process.exit(1);
}
// Save database object from the callback for reuse.
database = client.db();
console.log("Database connection done.");
// Initialize the app.
var server = app.listen(process.env.PORT || LOCAL_PORT, function () {
var port = server.address().port;
console.log("App now running on port", port);
});
});
/* "/api/status"
* GET: Get server status
* PS: it's just an example, not mandatory
*/
app.get("/api/status", function (req, res) {
res.status(200).json({ status: "UP" });
});
/* "/api/products"
* GET: finds all products
*/
app.get("/api/products", function (req, res) {
database.collection(PRODUCTS_COLLECTION).find({}).toArray(function (error, data) {
if (error) {
manageError(res, err.message, "Failed to get contacts.");
} else {
res.status(200).json(data);
}
});
});
/* "/api/products"
* POST: creates a new product
*/
app.post("/api/products", function (req, res) {
var product = req.body;
if (!product.name) {
manageError(res, "Invalid product input", "Name is mandatory.", 400);
} else if (!product.brand) {
manageError(res, "Invalid product input", "Brand is mandatory.", 400);
} else {
database.collection(PRODUCTS_COLLECTION).insertOne(product, function (err, doc) {
if (err) {
manageError(res, err.message, "Failed to create new product.");
} else {
res.status(201).json(doc.ops[0]);
}
});
}
});
/* "/api/products/:id"
* DELETE: deletes product by id
*/
app.delete("/api/products/:id", function (req, res) {
if (req.params.id.length > 24 || req.params.id.length < 24) {
manageError(res, "Invalid product id", "ID must be a single String of 12 bytes or a string of 24 hex characters.", 400);
} else {
database.collection(PRODUCTS_COLLECTION).deleteOne({ _id: new ObjectID(req.params.id) }, function (err, result) {
if (err) {
manageError(res, err.message, "Failed to delete product.");
} else {
res.status(200).json(req.params.id);
}
});
}
});
// Errors handler.
function manageError(res, reason, message, code) {
console.log("Error: " + reason);
res.status(code || 500).json({ "error": message });
}
More information about how to make MongoDB queries here.
有关如何进行MongoDB查询的更多信息,请参见此处 。
Using Postman (or your favorite tool), try to send requests to test the created endpoints:
使用邮递员 (或您喜欢的工具),请尝试发送请求以测试创建的端点:
⚠️ MongoDB database must be running locally and to start your Express server use thenpm start
command.
⚠️ 的MongoDB数据库必须在本地运行,并启动Express服务器使用npm start
命令。
Create a product
创建一个产品
![Image for post](https://miro.medium.com/max/9999/1*Bm0y6gBiwCrPqPPMrZSuww.png)
In the same time you can check your products collection inside the MongoDB database (I’m using Robot 3T for that):
同时,您可以在MongoDB数据库中检查产品集合(我正在使用Robot 3T ):
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/9a9912f6a46518403a56c4b812d734c3.png)
2. Get all products
2.获取所有产品
![Image for post](https://miro.medium.com/max/9999/1*tiNIYmK0k7kz29-e01piRQ.png)
3. Delete a product
3.删除产品
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/ee5325a1ed65c177e773d1e540855649.png)
奖金: (Bonus:)
Inside the GitHub repository, You will find a simple Angular screen using a service developed to manage the created endpoints:
在GitHub存储库中,您将找到一个简单的Angular屏幕,其中使用开发用于管理创建的端点的服务:
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { IProduct, Product } from './product.model';
@Injectable({
providedIn: 'root'
})
export class ProductService {
private productsUrl = '/api/products';
constructor(private http: Http) { }
// Get products
get(): Promise<Array<IProduct>> {
return this.http.get(this.productsUrl)
.toPromise()
.then(response => response.json())
.catch(this.error);
}
// Create product
create(product: Product): Promise<IProduct> {
return this.http.post(this.productsUrl, product)
.toPromise()
.then(response => response.json())
.catch(this.error);
}
// Delete a product
delete(id: string): Promise<any> {
return this.http.delete(`${this.productsUrl}/${id}`)
.toPromise()
.then(response => response.json())
.catch(this.error);
}
// Error handling
private error(error: any) {
let message = (error.message) ? error.message :
error.status ? `${error.status} - ${error.statusText}` : 'Server error';
console.error(message);
}
}
⚠️ To run the Angular app use the following command and check the http://localhost:4200
URL:
To️要运行Angular应用程序,请使用以下命令并检查http://localhost:4200
网址:
ng serve --proxy-config proxy.config.json
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/73c0331ead82bd1f62972b5f8cf0a547.gif)
有用的链接 (Useful links)
GitHub repository:
https://github.com/DjihadBengati/node-express-angular/tree/NODEJS_EXPRESS_ANGULAR_MANGODB
GitHub repository :
https GitHub repository :
//github.com/DjihadBengati/node-express-angular/tree/NODEJS_EXPRESS_ANGULAR_MANGODB
翻译自: https://medium.com/swlh/node-js-express-angular-mongodb-stack-3dcc5087b6d4