Egg.js + mongodb

The technology stack used in this paper includes node framework egg.js and mongodb database, and docker will be used for deployment, which will not involve the explanation of basic knowledge. Hopefully you have some knowledge of mongodb’s CURD operation and the basic syntax of Node.js. If so, start reading this article.

I. Environment construction

  1. Install Node 10.16.0 (at least 10.x)
  2. Installing the mongodb Database
  3. Docker /docker-compose install docker/docker-compose

Initialize the project

Refer to the official documentation for this step. The specific commands are as follows:

// Create the project directory
$ mkdir egg-mongo 
$ cd egg-mongo
/ / initialization
$ npm init egg --type=simple
// Install dependencies
$ npm install
Copy the code

Now that the framework of the project is set up, let’s start the project

$ npm run dev
// Enter localhost:7001 in the browser
127.0.0.1 localhost, make sure your host is correct
Copy the code

See Hi, Egg on the page, and the egg project is basically set up.

Third, directory structure

Here is the initial directory structure:

Take a look at these documents:

  1. The app directory is the most core, including controller, which mainly stores the code related to processing business logic. Router.js is the place to configure the browser routing address.

  2. The config directory is configuration-specific and now has only config.default.js and pluin.js files.

    Config.default. js is the file used to store the default configuration.

    Pluin.js is where the plug-in is introduced, and after being exported here, the app directory is accessible.

  3. The test directory holds the test code.

4. Add interfaces

Let’s use localhost:7001/users as an example to get the list of users:

In the Controller directory, add the user.js file, create a class UserController and inherit the controller from the egg.

// controller -> user.js
const Controller = require('egg').Controller

class UserController extends Controller {
    /** * Get the user list */
    getUserList() {
        const { ctx } = this;
        // Pretend to read data from the database
        const mockUsers = [
            { name: 'user1'.age: 18.sex: 'girl'.job: 'student' },
            { name: 'user2'.age: 19.sex: 'girl'.job: 'student' },
            { name: 'user3'.age: 20.sex: 'boy'.job: 'no job' },
        ]

        ctx.body = {
            code: 0.message: 'success'.data: mockUsers
        }
    }
}

module.exports = UserController;
Copy the code

Why inherit Controller? Because we’re going to use the EGG-wrapped CTX.

What is CTX? The egg encapsulates the HTPP request and response from the Node into the CTX of the controller.

const http = require('http')...// Send the HTTP header
// HTTP status: 200: OK
// The content type is text/plain
response.writeHead(200, {'Content-Type': 'text/plain'});

    // Send response data "Hello World"
response.end('Hello World\n'); .Copy the code

You can take a look at the framework API and source code, here is not detailed.

Step 2 map the routing table. In router.js, add the route and put the method in it.

// app -> router.js
module.exports = app= >{... router.get('/', controller.home.index)
  router.get('/users', controller.user.getUserList) // @add This is what we added
}
Copy the code

Restart the service and access localhost:7001/ Users to see the mockUsers data.

The third step is to write the Service. Some complex business logic is generally maintained in the Service. In the actual application, the Controller calls the Service, the Service calls db, and the Service returns the result to the Controller.

Create a service folder in the app directory and create a user.js file.

// service -> user.js
const Service = require('egg').Service

class UserSevice extends Service {
    /** * query all user */
    find() {
        // Not yet queried from database
        const mockUsers = [
            { name: 'user1'.age: 18.sex: 'girl'.job: 'student' },
            { name: 'user2'.age: 19.sex: 'girl'.job: 'student' },
            { name: 'user3'.age: 20.sex: 'boy'.job: 'no job'},]return Object.assign({}, {
            pageNum: 1.pageSize: 10.list: mockUsers
        })
    }
}

module.exports = UserSevice
Copy the code

Also modify the getUserList method of user.js in Controller:

. getUserList() {const { ctx } = this;
  	// Pretend to read data from the database
		const users = service.user.find()

  	ctx.body = {
    		code: 0.message: 'success'.data: users
  	}
}
...
Copy the code

The third step is to connect to mongodb. We use the egg-Mongoose library, so we don’t need to write the database connection by ourselves. This is also a library made by Egg and his family.

Since we use this library, let’s install it first.

$ npm install egg-mongoose --save
Copy the code

Place the installed plug-in in pluin.js.

// config -> pluin.js
exports.mongoose = {
		enable: true.// Start the plug-in
		package: 'egg-mongoose'
}
Copy the code

Add two files: config.local.js and config.prod.js to the config directory and write the following code:

// config -> config.local.js
exports.mongoose = {
    client: {
        url: 'mongo: / / 127.0.0.1:27017 / egg - mongo'.options: {}
    }
}

exports.baseUrl = 'http://127.0.0.1:7001';

// config.prod.js is not used in the production environment
Copy the code

Before we used the link library, we wrote:

// This code comes from runoob.com
const MongoClient = require('mongodb').MongoClient;
const url = "mongodb://localhost:27017/runoob";
 
MongoClient.connect(url, { useNewUrlParser: true }, (err, db) {
  if (err) throw err;
  console.log("Database created!");
  db.close();
});
Copy the code

It doesn’t look elegant at all, but does egg-Mongoose feel refreshing in comparison 😉

Ok, so let’s write the Schema. Create model folder in app directory and create user.js file with user Schema as follows:

// model -> user.js
module.exports = app= > {
    const mongoose = app.mongoose
    const Schema = mongoose.Schema;
    // According to the mock data, there are four fields: name/age/sex/job lastTime to mark the last change time
    const UserSchema = new Schema({
        name: {
            type: String
        },
        age: {
            type: Number
        },
        sex: {
            type: String
        },
        job: {
            type: String
        },
        lastTime: {
            type: Number}})// map to the users table of the egg-mongo db library (case insensitive)
    const User = mongoose.model('Users', UserSchema)
    
    // put the init method here
		initUserData(User)
  
    return User
}

function initUserData() {}
Copy the code

To see the effect of the database connection, add an initUserData method:

/** * Initialize a test User * @param {Object} User */
function initUserData(User) {
  	// Query the database
    User.find({}, (err, doc) => {
        if (err) {
            console.log(err)
            console.log('init user failed')}else if(! doc.length) {new User({
                name: 'UserInitName'.age: 23.sex: 'girl'.job: Program girl.lastTime: Date.now()
            }).save()
        } else {
            console.log('-------------init user successfully--------------')}}}Copy the code

Start the local mongo, which I installed on BREW, and open a new command line:

/ / installation
$ brew install mongodb
/ / start
$ cd /usr/local/mongodb/bin
$ sudo mongod
Copy the code

If you don’t get an error, mongodb will start. Go back to the egg-mongo command:

$ npm run dev
Copy the code

See the output * * — — — — — — — — — — — — — the init user successfully — — — — — — — — — — — — — – * * means that our database is ready.

5. Modify the user.js find method under Service to async await the database.

// Service -> user.js
/** * query all user */
async find() {
    // Query from database
    const users = await this.ctx.model.User.find({})

    return Object.assign({}, {
        pageNum: 1.pageSize: 10.list: users
    })
}
Copy the code

Change the method in Controller as well:

// Controller -> user.js
/** * Get the user list */
async getUserList() {
    const { ctx, service} = this // Get the service from this
    const users = await service.user.find() 

    ctx.body = {
        code: 0.message: 'success'.data: users
    }
}
Copy the code

Type localhost:7001/users in your browser and you’ll see the user in init!

{ code: 0, message: "success", data: { pageNum: 1, pageSize: 10, list: [ { _id: "5d5663f5129df2088e8c6783", name: "UserInitName", age: 23, sex: "girl", job: "girl", lastTime: 1565942773485, __v: 0}]}Copy the code

A simple interface is done.

Five, the other

The above implementation of the interface is quite simple, did not do login judgment, did not do authentication, also did not according to pageNum pageSize search conditions to query, it can be said that the leakage of all ah.

But this example is just a primer, not an in-depth understanding.

Code address: github.com/SUH11/egg-m…

Egg website: eggjs.org/zh-cn/intro…

License: