Mongoose is an Object Document Mapper (ODM). This means that Mongoose allows you to define objects with a strongly-typed schema that is mapped to a MongoDB document.

Mongoose provides an incredible amount of functionality around creating and working with schemas. Mongoose currently contains eight SchemaTypes that a property is saved as when it is persisted to MongoDB. They are:

Further to these common options, certain data types allow you to further customize how the data is stored and retrieved from the database. For example, a String data type also allows you to specify the following additional options:

Mongoose

Mongoose models provide several static helper functions for CRUD operations. Each of these functions returns a mongoose Query object.

Below is the list of common queries we may use for the course.

Model.deleteOne()

delete one document in the collection match condition

Model.find()

find all and return all documents of the collectetion

Model.findById()

find collection by mongo id

Model.findByIdAndDelete()

find collection by mongo id and delete the collection

Model.findByIdAndUpdate()

find collection by mongo id and update the collection info

Model.findOne()

find the first match collection with the condition

Model.findOneAndUpdate()

find collection by matched condition and update the collection info

A full list of Mongoose queries could be find here

This starting guide is from the official Mongoose guide

$ npm install mongoose

Now say we like fuzzy kittens and want to record every kitten we ever meet in MongoDB. The first thing we need to do is include mongoose in our project and open a connection to the test database on our locally running instance of MongoDB.

// getting-started.js
const mongoose = require("mongoose");
mongoose.connect("mongodb://localhost:27017/test", {
  useNewUrlParser: true,
  useUnifiedTopology: true,
});

We have a pending connection to the test database running on localhost. We now need to get notified if we connect successfully or if a connection error occurs:

const db = mongoose.connection;
db.on("error", console.error.bind(console, "connection error:"));
db.once("open", function () {
  // we're connected!
});

Once our connection opens, our callback will be called. For brevity, let's assume that all following code is within this callback.

With Mongoose, everything is derived from a Schema. Let's get a reference to it and define our kittens.

const kittySchema = new mongoose.Schema({
  name: String,
});

So far so good. We've got a schema with one property, name, which will be a String. The next step is compiling our schema into a Model.

const Kitten = mongoose.model("Kitten", kittySchema);

A model is a class with which we construct documents. In this case, each document will be a kitten with properties and behaviors as declared in our schema. Let's create a kitten document representing the little guy we just met on the sidewalk outside:

const silence = new Kitten({ name: "Silence" });
console.log(silence.name); // 'Silence'

Kittens can meow, so let's take a look at how to add "speak" functionality to our documents:

// NOTE: methods must be added to the schema before compiling it with mongoose.model()
kittySchema.methods.speak = function () {
  const greeting = this.name
    ? "Meow name is " + this.name
    : "I don't have a name";
  console.log(greeting);
};
const Kitten = mongoose.model("Kitten", kittySchema);

Functions added to the methods property of a schema get compiled into the Model prototype and exposed on each document instance:

const fluffy = new Kitten({ name: "fluffy" });
fluffy.speak(); // "Meow name is fluffy"

We have talking kittens! But we still haven't saved anything to MongoDB. Each document can be saved to the database by calling its save method. The first argument to the callback will be an error if any occurred.

fluffy.save(function (err, fluffy) {
  if (err) return console.error(err);
  fluffy.speak();
});

Say time goes by and we want to display all the kittens we've seen. We can access all of the kitten documents through our Kitten model.

Kitten.find(function (err, kittens) {
  if (err) return console.error(err);
  console.log(kittens);
});

We just logged all of the kittens in our db to the console. If we want to filter our kittens by name, Mongoose supports MongoDBs rich querying syntax.

Kitten.find({ name: /^fluff/ }, callback);

This performs a search for all documents with a name property that begins with "fluff" and returns the result as an array of kittens to the callback.

Congratulations That's the end of our quick start. We created a schema, added a custom document method, saved and queried kittens in MongoDB using Mongoose. Head over to the guide, or API docs for more.

This tutorial is about the work flow for the CRUD process of User Account. This will enable these features for our server:

While also maitain these api standards of :

If there are different roles of users in your system, you should pre-define who can see/do what. Example: we allow everyone to see the list of products so the endpoint will look like:

/**
 * @route GET api/products?page=1&limit=10
 * @description Get products with pagination
 * @access Public
 */

But if user want to write a review, they need to login, so the endpoint will be defined:

/**
 * @route POST api/review
 * @description Create a new review for a product
 * @access Login required
 */

A modern authentication flow could be explained by the following diagram.

jwt

The whole process will be like this:

User start login

ruote("/login", callback1, callback2, callback3, lastcallback);
//The last callback is usually where everything end and send back the response to Client
//This make all the callback functions in between call "Middlewares"
//However, we won't use any middleware for this `login` route

After user login

Add access_token to future requests

After successfully login, the Front End will receive a access_token that is unique to the current user. To use this key for authorization in access protected backend route, here is the step for front end

import api from ".//////";

const login = (email, password) => async (dispatch) => {
  //logic here
  const result = await api;
  api.defaults.headers.common["authorization"] = "Bearer " + result.accessToken; //adding authorization: "Bearer asdfasdfasdfasdf" to the every request object that sent to server
};

Future request sent to backend protected route

We will now use JWT library to help validate the request. To make this an Authenticated Protected route, we need to use Authentication Middleware like

route("/secured", authenticationMiddleware, Controller);

a) Get data of a specific user with id

Delete data of a specific user with id