Introduction of koa

Koa is a new Web framework. By making use of async functions, Koa helps you discard callback functions and greatly enhances error handling.

Installation of koa

cnpm i koa -S

1. Set up a simple server using KOA

1.1 Introduction of Modules

1.2 Instantiating an APP

1.3 app. Listen () to monitor

/ / introduction
const Koa = require('koa')
// instantiate app
const app = new Koa();

/ / to monitor
app.listen(3000);
Copy the code

2. Use of middleware

Middleware is an asynchronous function that preprocesses our requests and responses

app.use(async (ctx,next)=>{})

  • CTX: Context
    • The Koa Context encapsulates the Node’s request and Response objects into a single object
  • Await next() as a dividing line between request and response (see code comments)

Ps: Because this is an asynchronous operation, it will wait until all the request part of app.use is finished and then continue processing corresponding part according to await next(), so it is called the dividing line between request and response

const Koa = require('koa')
const app = new Koa();

app.use(async (ctx,next)=>{
  // Process the request

  await next(); // It is equivalent to the split line between request and response
  // Process the response
  const rt = ctx.response.get('X-response-Time');
  console.log(`${ctx.method} ${ctx.url} - ${rt}`);
})

// x-response-time
app.use(async (ctx, next) => {
  // Get the current time at request time
  const start = Date.now();
  await next(); 
  // Current time - request time
  const ms = Date.now() - start;
  ctx.set('X-response-Time'.`${ms}ms`);
})

//response
app.use(async ctx => {
  ctx.status = 200;
  ctx.type = 'html';
  ctx.body = 'hello qlq';
})

app.listen(3000);
Copy the code

3. Use of error-handling middleware

3.1 First simulate an error ctx.throw(401,’ error ‘)

Ctx. throw(401,’ error ‘) equals

  const err = new Error('wrong');
  err.status = 401;
  // Expose is an error that applies to clients
  err.expose = true;
  throw err;
Copy the code

3.2 Listen for error methods with koa.on ()

app.on('error'.err= >{
  console.log(err.message);
})
Copy the code

3.3 Build an error-handling middleware to handle errors

Ctx.app. emit(‘error’,error, CTX) to emit app.on() to listen for error

Ps: Error-handling middleware must be written at the top of all middleware

const Koa = require('koa')
const app = new Koa();

Error handling middleware must be written at the top of all middleware
app.use(async (ctx,next)=>{
  try {
    await next();
  } catch (error) {
    // Display the status code to the user
    ctx.status = error.status || 500;
    console.log(ctx.status);
    // The front-end initiates an Ajax request
    ctx.type = 'json';
    ctx.body = {ok:0.message: error.message}
    // Manually trigger the global error function
    ctx.app.emit('error',error,ctx)
  }
})

Ctx.throw () is the API interface of the middleware request
app.use(async ctx => {
  // The request comes in
  ctx.throw(401.'There was an error')})// koA listens for error methods
app.on('error'.err= >{
  console.log(err.message);
})

app.listen(3000);
Copy the code

4. Use koA-onError middleware to handle errors

4.1 Download KOA-onError and introduce fs module

4.2 onError (app) to listen

4.3 Ctx. body = fs.createreadstream (‘not exist’) in catch of error-handling middleware

const Koa = require('koa')
const onerror = require('koa-onerror')
const fs = require('fs')
const app = new Koa();

/ / onerror monitor app
onerror(app);

// Middleware functions for error handling
app.use(async ctx=>{
  try {
    await next();
  } catch (error) {
    ctx.body = fs.createReadStream('not exist')
  }
})

app.use(async ctx =>{
  ctx.throw(401.'wrong')
})

app.on('error'.err= >{
  console.log(err.message);
})

app.listen(3000);
Copy the code

5. Use of KOA-Logger middleware

5.1 Downloading and Importing the KOA-Logger

5.2 App. use(Logger) can obtain the request and response time and other information

Such as:

const Koa = require('koa')
const logger = require('koa-logger')
const app = new Koa();
app.use(logger())

app.listen(3000);
Copy the code

6. Use of KOA-Router middleware

Download the koa – the router

6.1 Creating a Router Folder to Install Routes. Create an index.js

6.2 Introduce the KOA-Router and instantiate a router and throw the router

6.3 router.get/post(‘ path ‘,(CTX,next)=>{})

Get /post () is used as much as app.get/post () in Node

6.4 Importing a Router File and Registering routes in a Server File

Importing a Router File

const routerIndex = require('./router')
Copy the code

Registered routing

app.use(routerIndex.routes());
app.use(routerIndex.allowedMethods());
Copy the code

6.5 Router. post(CTX =>{ctx.request.body}) Cannot obtain the request body

You need to download additional KOA-BodyParser for processing to get the parameters of the request body and download and import koA-BodyParser from the server file

const bodyParser = require('koa-bodyparser')
app.use(bodyParser());
Copy the code

This will get ctx.request.body information in the routing file

6.6 await ctx.render(‘ file name to render ‘, data to render)

Route file index.js code

const Router = require('koa-router')
const router = new Router();
// Routing middleware processes the request definition API interface

router.get('/'.async (ctx,next)=>{
  // Render a page template engine HBS

  // Get the data from the database
  const data = {
    title: 'I don't want mongdb.'.subTitle: 'hello hubs'.htmlStr:'< h3 > < / h3 > hello my lack of money'.isShow: false.username:'Joe'.a: true.b: true.arr: ['a'.'c'.'e'].users:[
      {
        name:'yellow'.age: 12.birthday:new Date(1999.2.2)}, {name: 'little red'.age: 13.birthday: new Date(1993.2.2)}, {name: 'the little green'.age: 14.birthday: new Date(1992.2.2)},]}await ctx.render('index',data) // Views file
})

router.get('/login'.async (ctx, next) => {
  / / redirection
  ctx.redirect('/sign')
})

router.get('/sign'.async (ctx, next) => {
  ctx.body = 'Registration Page'
})

router.post('/'.ctx= >{
  // The POST request requires an additional download of KOA-BodyParser for processing to get the parameters of the request body
  console.log(ctx.request.body);
  ctx.body = { 'ok':1}})module.exports = router;
Copy the code

Server file code

const Koa = require('koa')
const app = new Koa();
// KoA-bodyParser is required to handle the post request body parameters in KOA
const bodyParser = require('koa-bodyparser')
// Import a route
const routerIndex = require('./router')

app.use(bodyParser());

// Register the route
app.use(routerIndex.routes());
app.use(routerIndex.allowedMethods());

app.listen(3000);
Copy the code

7. Params, Query, Context namespace, static resource middleware

7.1 params

7.1.1 Creating a Routing server file of a User Automatically imports and registers corresponding routes

7.1.2 router.prefix(‘/user’) The path name used below will be automatically added to prefix

7.1.3 Params handles router.get(‘/:id/:pid’)

The path name followed by: indicates that the following property is params

7.1.4 Params can be obtained directly using ctx.params in the callback function

7.2 the query

http://localhost:3000/user?name=zhangsan&age=18 with CTX. The query can obtain {name = zhangsan, the age 18 =}

7.3 Context Namespace

The namespace of the context object names all routes using the data in state

ctx.state.xx={};

Ctx.state. navList={a:1}; Ctx.state. navList is available on all routers

7.4 Static Resource Middleware

Set the static resource server, which is used to set the path for obtaining resources such as images. Set the public file to hold resources such as images

7.4.1 Download and import KOA-static

const static = require('koa-static')
Copy the code

7.4.2 Configuring a Static Resource Server

app.use(static(__dirname+'/public'))
// SRC ='/images/1.png' public images 1.png
Copy the code
Routing user code
const Router = require('koa-router')
const router = new Router({
  prefix: '/user'
});
// router.prefix('/user');

// http://localhost:3000/user? name=zhangsan&age=18
router.get('/'.(ctx,next) = >{
  console.log(ctx.state.navList);
  console.log(ctx.query);
  ctx.body = "I'm a user page"
})

// http://localhost:3000/user/1/3
router.get('/:id/:pid'.(ctx,next) = >{
  console.log(ctx.params);
  ctx.body = 'parmas usage'
})

module.exports = router;
Copy the code
Server code
const Koa = require('koa')
const app = new Koa();

// KoA-bodyParser is required to handle the post request body parameters in KOA
const bodyParser = require('koa-bodyparser')

// Import a route
const routerIndex = require('./router')
const routerUser = require('./router/user')

// Introduce static resource file middleware
const static = require('koa-static')

app.use(async (ctx,next)=>{
  // The namespace of the context object can name all routes using the data in state
  ctx.state.navList = {
    a:1
  }
  await next();
})

app.use(bodyParser());

// Set up the static resource server
app.use(static(__dirname+'/public'))
//src='/images/1.png'

// Register the route
app.use(routerIndex.routes());
app.use(routerIndex.allowedMethods());
// Register user routing
app.use(routerUser.routes());
app.use(routerUser.allowedMethods())

app.listen(3000);
Copy the code

Koa-hbs template engine

Render the template to the front page

8.1 Downloading server files and importing KOA-HBS

const hbs = require('koa-hbs')
Copy the code

8.2 Registering middleware for the Template Engine

App. Use (HBS) middleware (configuration of {})

  • ViewPath: indicates the root directory of the view
  • DefaultLayout: defaultLayout file
  • PartialsPath: public views path
  • DisableCache: indicates whether to cache
app.use(hbs.middleware({
  viewPath:__dirname+'/views'.// The root directory of the view
  defaultLayout:'layout'.partialsPath:__dirname+'/views/partials'./ / public views
  disableCache: true // No caching during development
}))
Copy the code

Create the default layout layout.hbs (HBS file)

Layout. HBS is an HTML file written with {{}} body inserted with {{> public views}} nav and foot under partials

The main content part of the fixed writing method is fixed under the views index. HBS file

Layout. The hub code
<! DOCTYPEhtml>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
  <title>{{title}}</title>
  <link rel="stylesheet" href="/styles/index.css">
  {{#block 'indexCss'}}{{/block}}
</head>
<body>
  {{! -- Navigation --}}
  {{>nav}}
  {{! }}
  {{{body}}} {{! -- index.hbs --}} 
  {{! - feet -}}
  {{>foot}}

  {{! -- Code move is a block --}}
  <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
  {{#block 'jquery'}}{{/block}}
</body>
</html>
Copy the code

8.4 Use Handlebars -helpers middleware in index.hbs

It’s best to download Handlebars -helpers because native KOA-HBS doesn’t have many methods for interpolating references

const helpers = require('handlebars-helpers')
helpers.comparison({
  handlebars:hbs.handlebars
})
Copy the code

For more information: github.com/helpers/han…

8.5 Await ctx.render(‘ HBS to be displayed ‘, data to be transmitted) in route

For example look at the code for index.hbs (all the data is in the index view above use ctx.render())
{{! -- Body content --}}

{{#contentFor 'indexCss'}}
<style>
  h3 {
    color: red
  }
</style>
{{/contentFor}}

{{! -- Interpolation binding (double curly braces) --}}
<h3>{{subTitle}}</h3>

{{! -- Insert HTML (three parentheses) --}}
<div>{{{htmlStr}}}</div>

{{! -- if (#if) --}
{{#if isShow}} 
<p>{{username}}Welcome!</p>
{{else}}
<a href="http://localhost:3000/login">Please log in</a>
{{/if}}

{{! - cycle -}}
<ul>
  {{#each users }}
    <li>{{name}}-{{age}}-{{data birthday 'YYYY/MM/DD'}}</li>
  {{/each}}
</ul>

<div>
  {{#and a b}}A and b are true{{/and}}
</div>

<div>
  {{#contains arr 'e'}}E is in the array{{else}}E is not in the array{{/contains}}
</div>

{{! -- js --}}
{{#contentFor 'jquery'}}
<script>
  $(function(){
    console.log('content for jquery');
  })
</script>
{{/contentFor}}
Copy the code

8.6 Code move

In the default layout file, layout. HBS uses {{#block ‘block name ‘}}{{/block}} to refer to where the code is moved to. In other view files {{#contentFor ‘block name ‘}}

Ex. :

{{#contentFor 'jquery'}}
<script>
  $(function(){
    console.log('content for jquery');
  })
</script>
{{/contentFor}}
Copy the code
{{#block 'jquery'}}{{/block}}
Copy the code