Use of Service in Egg.js

Service service

Service is used to write business logic code that interacts directly with the database. Service is an abstraction layer used to encapsulate business logic in complex business scenarios.

To put it simply, the business logic code is further refined and classified, so the code that interacts with the database is placed in Service. There are three obvious advantages to doing this.

  • Keep the logic in the Controller more concise,
  • Maintain the independence of business logic, and the abstracted Service can be called by multiple Controllers.
  • Separating logic and presentation makes it easier to write test cases.

As long as the interaction with the database is written in the Service, if you use the Egg framework, you must abide by its conventions.

Create a new zhuba.js file in the /app/service directory and write your own service:

'use strict'
const Service = require("egg").Service
class zhuBaService extends Service {<!-- -->
async getGirl(id) (//Simulation data
  return{<!-- -->
    id: id,
    name: 'kunkun',
    age: 28
  }
}
module.exports = zhuBaService;
// Call service
async getGir12() {<!-- -->
  const {<!-- -->ctx} = this;
  const res = await ctx.service.zhuba.getGirl('18');
  ctx.body = res
}

image.png

Service method callability

After a service method is completed, it can be used in other Controllers. For example, use it in home.js. Open the /app/controller/home.js file, create a new testGetGirl() method, and then add a route so that the id can be obtained by the database.

async testGetGir1() (
  const ctx = this.ctx;
  let id = ctx.query.id;
  const res = await ctx.service.zhuba.getGirl(id)
  ctx.body = res;
}

image.png

When naming it, it is best to match it with the Controller. The writing method is similar to that of Controller, and the data provided by Service can be obtained under any Controller.

Using EJS template engine in View

Template engine

There are many optional templates, please refer to the official documentation for details.

Benefits of server-side rendering

  • It is very friendly to SEO. Single-page applications, such as Vue, are generated on the client side. This kind of application cannot be crawled by domestic search engines, so SEO will not have good results. Therefore, if it is a display or promotional website such as an official website, news website, or blog, server-side rendering technology must be used.
  • Back-end rendering is an old development model, and its rendering performance is unanimously recognized. In the PHP era, this back-end rendering technology reached its peak.
  • To supplement the development model of front-end and back-end separation, not all functions can be separated from front-end and back-end. Especially in the popular mid-end systems, there are many principles of once-login, available everywhere. At this time, server-side rendering is needed to help.

EJS1

Write in plugin.js:

'use strict'
/**@type Egg.EggPLugin */

module.exports = {<!-- -->
  // had enabLed by egg
  //static: {<!-- -->
  // enable: true,
  //}
  ejs: {<!-- -->
   enable: true,
   package: "egg-view-ejs"
  }
}

In config.default.js

'use strict';
const path = require('path');

/**
 * @param {Egg.EggAppInfo} appInfo app info
 */
module.exports = appInfo => {<!-- -->
  /**
   * built-in config
   * @type {Egg.EggAppConfig}
   **/
  const config = exports = {<!-- -->};

  // use for cookie sign key, should change to your own and keep security
  config.keys = appInfo.name + '_1575812978932_7706';

  // add your middleware config here
  config.middleware = [];

  config.security = {<!-- -->
    csrf: {<!-- -->
      enable: false,
    },
  };

  config.view = {<!-- -->
    mapping: {<!-- -->
      ".html": "ejs"
    },
    root: [
      path.join(appInfo.baseDir, "app/html"),
      path.join(appInfo.baseDir, "app/view")
    ].join(",")
  };

  config.ejs = {<!-- -->
    delimiter: "%"
  };

  config.static = {<!-- -->
    prefix: "/assets/",
    dir: path.join(appInfo.baseDir, "app/assets")
  };

  config.session = {<!-- -->
    key: "MUKE_SESS",
    httpOnly: true,
    maxAge: 1000 * 50,
    renew: true
  };

  // add your user config here
  const userConfig = {<!-- -->
    // myAppName: 'egg',
  };

  return {<!-- -->
    ...config,
    ...userConfig,
  };
};

In zhuba.js

class zhubaController extends Controller (
async index() {<!-- -->
  const ctx = this.ctx;
  await ctx.render('zhuba.html' )
}

Create a new zhuba.html file under /app/view/ and it will be rendered. Just access the routing address.

image.png

EJS2

Display data in controller (<%= parameter %>)

class zhubaController extends Controller{<!-- -->
async index() {<!-- -->
  const {<!-- -->ctx} = this;
  await ctx.render('zhuba.html',{<!-- -->
    ID: 2001,
    name: 'kunkun',
    age: 18,
    skills: ['sing', 'jump', 'Rap', 'basketball']
  })
}

Loop display of data (for)

<h1>Hello ZhuBa!</h1>
<h2>id: <%= id%>, name: <%= name%>, age: <%= age%>
</h2>
<br />
<ul>
  <% for(let i=; i < skills.length; i + + )( %>
    <li>
      <%= skills[i] %>
    </li>
    <%}%>
</ul>

Modify default delimiter

config.ejs={<!-- -->
  delimiter: "$"
}

EJS3

The use of public code snippets only requires writing some code snippets, that is, extracting the public parts (component idea)

<%- include('header.html') %>

Configure static resources: In the /app/public directory, you can directly access the file content without configuring routing, because Egg uses the egg-static plug-in.

image.png

image.png

Modify config.default.js to change access to public to assets. Of course, using public at this time will result in 404

onfig.static = {<!-- -->
  prefix:"/assets/"
}

Use static resources in .html

Consistent with normal use

image.png

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>user</title>
  <link rel="stylesheet" type="text/css" href="assets/css/user.css"/>
</head>
<body>
  <h2>
    id: <%= id%>, name: <%= name%>, age: <%= age%>
  </h2>
  <script src="assets/js/user.js"></script>
</body>
</html>