1. Nodejs understanding

  1. Nodejs is not developed for the purpose of developing server-side apis. Its main purpose is to enable JS to run without the browser. It has many application directions, because it is not for the purpose of developing server-side apis. As a result, there are many nodeJs-based frameworks dedicated to developing server-side apis.
  2. Nodejs application:

    1. NodeJS Stream (Front-end Engineering)
    2. Write the server API
    3. As an intermediate layer

2. Characteristics of koa

In short, it can be summarized as two points: simplified and onion model.

3. The simplest use of KOA

// (1) import koA
const Koa  = require('koa')

// (2) KOA instantiation, that is, using KOA. This app instance is also called an application object, and its biggest feature is that it contains a lot of middleware on it
const app = new Koa()

// (3) Multiple middleware can be registered. CTX refers to the context and next refers to the next middleware
app.use((ctx, next) = > {
 next()
})

// (4) enable koA
app.listen(3000)Copy the code

Remark:

  • Middleware is actually a function. After the function is registered, it becomes middleware. App.use () is registered middleware.
  • The first middleware executes automatically, the other middleware needs to be called by the developer.

4. Understanding of the middleware function next()

  • Next () must return a promise, and you can use a callback or async or await to get the promise.
  • Middleware can have return values.
  • The reason async is often needed when registering middleware: internally use await

5. Understanding the middleware context CTX

  • CTX is a state object that contains some native Node related objects.
  • It is important to note that this object persists throughout the life of the request.

Understanding of async await

  • Async: The return value of a function with async is wrapped as a promise.
  • Await :(1) can be treated as an evaluation keyword, await computes the promise returned by next() and converts it to a value. (2) Block the current thread.

7. Onion model

Conclusion first: it is better for all middleware to have async and await, because without async and await, all middleware execution is not guaranteed to follow the Onion model.

const Koa  = require('koa')

const app = new Koa()

app.use((ctx, next) = > {  
    console.log(1) 
    next()  
    console.log(2)
})

app.use(async(ctx, next) => {  
    console.log(3)  
    const axios = require('axios')  
     // (a) the await here will block the code
    const res = await axios.get('http://www.baidu.com')
    next()  
    console.log(4)
})

app.listen(3000)Copy the code

The result of the above code execution is: 1, 3, 2, 4. The first middleware does not execute according to the Onion model, because the code at (a) will block the current thread, so 2 will be printed after printing 3, and finally 4 will be printed after the code at (a) finishes executing.

If the first middleware is added with async await, both middleware will execute in strict accordance with the Onion model and the code execution result becomes: 1, 3, 4, 2.

8. Automatic route loading

1. Koa-router classic introductory code example

const Koa  = require('koa'); // (1) const Router = require('koa-router'); const app = new Koa(); Const router = new router (); const router = new router (); Router.get (koa-router) {// if (koa-router) {// if (koa-router) {'/'App.use (router.routes())app.listen(3000);Copy the code

  • The actual return to the client should be JSON data, koA has already done the processing, only need to return an object will automatically become JSON format.
  • Theoretically, all interface apis can be written in one file above, but this is not conducive to code maintenance. Therefore, it is necessary to divide the topic and write related or similar API interfaces in the same file. At this time, the project architecture is changed into the following format:

2. Split routes with multiple routers

// app.js

const Koa  = require('koa');

/ / (1) the import
const book = require('./api/v1/book');
const classic = require('./api/v1/classic');
const app = new Koa();

// (2) register
app.use(book.routes());
app.use(classic.routes());
app.listen(3000);Copy the code

// book.js

const Router = require('koa-router');
const router = new Router();

router.get('/v1/book/latest', (ctx, next) => {  
    ctx.body = {    key: 'book'}})module.exports = routerCopy the code

// classic.js

const Router = require('koa-router');
const router = new Router();

router.get('/v1/classic/latest', (ctx, next) => {
  ctx.body = {    key: 'classic'}})module.exports = routerCopy the code

Rules for importing modules: Upper-layer modules can import lower-layer modules, and lower-layer modules should avoid importing upper-layer modules.

Front-end API version number transmission mode:

  1. Path: v1 / list
  2. Query parameters: /list? version=v1
  3. In the header

The introduction and registration of route module in app.js are too tedious, so require-directory can be used to realize automatic file loading and automatic registration.

3. Require-directory automatically imports files and automatically registers middleware

(1) Install the plug-in

npm install require-directory --saveCopy the code

(2) Use

Function:

  • Automatically loads all files in a directory
  • Automatic registration

// app.js

const Koa  = require('koa');const Router = require('koa-router');

/ / (1) the import

const requireDirectory = require('require-directory');

const app = new Koa();

// (2) Automatically import all modules in a directory

// module is a fixed word

// './ API 'is the path, usually a folder, supports nested paths

// The third argument can be interpreted as: execute this function every time a module is loaded

requireDirectory(module.'./api', {  visit: whenLoadModule})

// (3) Automatic registration
function whenLoadModule(obj) { 
 if(obj instanceof Router) {    
    app.use(obj.routes())  
}}

app.listen(3000);Copy the code



The above content from lesson for actual combat coding.imooc.com/class/342.h…