Web application development framework-egg (3) 01-Basic functions – the directory structure agreed by the framework, the directory specified by the built-in plug-in & built-in objects Application, context, Request & Response, Controller ,Service,Helper,config
Basic functions
Conventions of directory structure
Egg’s principle: Agreement is greater than configuration
egg-project ├── package.json ├── app.js (optional) ├── agent.js (optional) // More unique ├── app | ├── router.js │ ├── controller │ | └── home.js │ ├── service (optional) │ | └── user.js │ ├── middleware (optional) │ | └── response_time.js │ ├── schedule (optional) │ | └── my_task.js │ ├── public (optional) │ | └── reset.css │ ├── view (optional) │ | └── home.tpl │ └── extend (optional) │ ├── helper.js (optional) │ ├── request.js (optional) │ ├── response.js (optional) │ ├── context.js (optional) │ ├── application.js (optional) │ └── agent.js (optional) ├── config | ├── plugin.js | ├── config.default.js │ ├── config.prod.js | ├── config.test.js (optional) | ├── config.local.js (optional) | └── config.unittest.js (optional) └── test ├── middleware | └── response_time.test.js └── controller └── home.test.js
Directory specified by the framework
app/router.js
is used to configure URL routing rules.app/controller/**
is used to parse user input and return corresponding results after processing.app/service/**
is used to write the business logic layer, optional.app/middleware/**
is used to write middleware, optional.app/public/**
is used to place static resources, optional.app/extend/**
is used for extensions to the framework, optional.config/config.{env}.js
is used to write configuration files.config/plugin.js
is used to configure the plug-ins that need to be loaded.test/**
is used for unit testing.app.js
andagent.js
are used to customize the initialization work at startup, optional.
Directory agreed upon by built-in plug-ins
app/public/**
is used to place static resources, optional.app/schedule/**
is used for scheduled tasks, optional.
Built-in objects
In this chapter, we will briefly introduce some of the basic objects built into the framework, including the four objects inherited from Koa (Application, Context, Request, Response) and some objects extended by the framework (Controller, Service, Helper, Config, Logger), we will encounter them frequently in subsequent courses.
Application
Application is a global application object. In an application, only one will be instantiated. It inherits from Koa.Application, on which we can mount some global methods and objects. We can easily extend the Application object in a plug-in or application.
Event
When the framework is running, some events will be triggered on the Application instance. Application developers or plug-in developers can listen to these events and perform some operations. As application developers, we usually monitor when launching custom scripts.
server
: This event will only be triggered once per worker process. After the HTTP service is started, the HTTP server will be exposed to developers through this event.error
: When any exception occurs during runtime and is caught by the onerror plug-in, theerror
event will be triggered, exposing the error object and associated context (if any) to the developer. You can Carry out customized log record reporting and other processing.request
andresponse
: When the application receives a request and responds to a request, therequest
andresponse
events will be triggered respectively, and Exposing the current request context, developers can listen to these two events for logging.
// app.js module.exports = app => {<!-- --> app.once('server', server => {<!-- --> // websocket }); app.on('error', (err, ctx) => {<!-- --> // report error }); app.on('request', ctx => {<!-- --> // log receive request }); app.on('response', ctx => {<!-- --> // ctx.starttime is set by framework const used = Date.now() - ctx.starttime; // log total cost }); };
How to obtain
// app.js module.exports = app => {<!-- --> app.xxxx = 'xxxx'; };
controller file
class UserController extends Controller {<!-- --> async fetch() {<!-- --> this.ctx.body = this.app.xxxx; } }
Like Koa, on the Context object, the Application object can also be accessed through
ctx.app
.
context
Context is a request-level object, inherited from Koa.Context. Each time a user request is received, the framework will instantiate a Context object, which encapsulates the information of the user request and provides many convenient methods to obtain request parameters or set response information. The framework will mount all Services on the Context instance, and some plug-ins will also mount some other methods and objects on it (egg-sequelize will mount all models on the Context).
How to obtain
The most common ways to obtain Context instances are in Middleware, Controller and Service. The acquisition method in the Controller has been demonstrated in the above example. The acquisition method in the Service is the same as the acquisition method in the Controller. Obtaining the Context instance in the Middleware is the same as the way the Koa framework obtains the Context object in the middleware.
In addition to obtaining the Context instance when requesting, in some non-user request scenarios we need to access objects on the Context instance such as service / model. We can create one through the Application.createAnonymousContext()
method Anonymous Context instance:
// app.js module.exports = app => {<!-- --> app.beforeStart(async () => {<!-- --> const ctx = app.createAnonymousContext(); // preload before app start await ctx.service.posts.load(); }); }
Each task in the scheduled task accepts a Context instance as a parameter so that we can more conveniently execute some scheduled business logic:
// app/schedule/refresh.js exports.task = async ctx => {<!-- --> await ctx.service.posts.refresh(); };
Request & amp; Response
Request is a request-level object, inherited from Koa.Request. It encapsulates the Node.js native HTTP Request object and provides a series of auxiliary methods to obtain common parameters of HTTP requests.
Response is a request-level object, inherited from Koa.Response. Encapsulates the Node.js native HTTP Response object and provides a series of auxiliary methods to set HTTP responses.
// app/controller/user.js class UserController extends Controller {<!-- --> async fetch() {<!-- --> const {<!-- --> app, ctx } = this; const id = ctx.request.query.id; ctx.response.body = app.cache.get(id); } }
Controller
The framework provides a Controller base class and recommends that all Controllers inherit from this base class implementation. The Controller base class has the following properties:
ctx
– The Context instance of the current request.app
– The Application instance of the application.config
– Application configuration.service
– applies to all services.logger
– The logger object encapsulated for the current controller.
In a Controller file, you can reference the Controller base class in two ways:
// app/controller/user.js // Get it from egg (recommended) const Controller = require('egg').Controller; class UserController extends Controller {<!-- --> //implement } module.exports = UserController; // Get from app instance module.exports = app => {<!-- --> return class UserController extends app.Controller {<!-- --> //implement }; };
Service
The framework provides a Service base class and recommends that all Services inherit from this base class implementation.
The properties of the Service base class are the same as those of the Controller base class, and the access methods are similar:
// app/service/user.js // Get it from egg (recommended) const Service = require('egg').Service; class UserService extends Service {<!-- --> //implement } module.exports = UserService; // Get from app instance module.exports = app => {<!-- --> return class UserService extends app.Service {<!-- --> //implement }; };
Helper
Helper is used to provide some practical utility functions. Its function is that we can extract some commonly used actions into an independent function in helper.js, so that complex logic can be written in JavaScript to avoid the logic being scattered everywhere, and at the same time, test cases can be written better.
Helper itself is a class with the same properties as the Controller base class. It will also be instantiated on each request, so all functions on Helper can also obtain context information related to the current request.
How to obtain
The currently requested Helper(ctx.helper
) instance can be obtained on the Context instance.
// app/controller/user.js class UserController extends Controller {<!-- --> async fetch() {<!-- --> const {<!-- --> app, ctx } = this; const id = ctx.query.id; const user = app.cache.get(id); ctx.body = ctx.helper.formatUser(user); } }
In addition, Helper instances can also be obtained in templates.
config
We can get the config object from the Application instance through app.config
, or we can get the config object from the Controller, Service, Helper instance through this.config
.