preface

As technology continues to evolve, front-end engineers are given more and more responsibilities. It is no longer the case that you just need to cut an image and add a CSS style to complete the task. In this article, complete a simple login to get you started quickly and become a ‘mini full stack engineer’. Here we Go!

Koa starts fast

The installation

  • Since Node.js v7.6.x already fully supports async/await syntax, make sure node is above version 7.6
  • The recommended multi-version management tool for Node is NVM. How to install here will not repeat, there are many online tutorials
    • Github.com/creationix/…

// Initialize package.json
npm init

/ / koa2 installation
npm install koa

Copy the code

A hello world

Create a new index.js and type the following code


//index.js

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

app.use( async (ctx, next) => {
  ctx.response.body = 'Hello, I'm Daniel Wu from mainland China'
})

app.listen(3333, () = > {console.log('server is running at http://localhost:3333')})Copy the code

On our command line

node index.js
Copy the code

Then you can see the result:

Several core concepts

Middleware good gay friends CTX and Next

In the code above, we can see that app.use uses two parameters, CTX and next

ctx

CTX is used as a context, and Koa wraps node’s Request and Response objects into a single object. Ctx. request and ctx.response. Some commonly used properties or methods are brokered within Koa so that we can retrieve them directly through CTX. For example, ctx.request.url can be written as ctx.url.

next

The next parameter transfers control of processing to the next middleware

The classic onion diagram concept explains next’s execution well, with requests coming in from the outermost layer and coming out from the innermost layer. Let’s look at an example

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

app.use(async (ctx, next)=>{
  let startTime = new Date().getTime()
  await next()
  let endTime = new Date().getTime()
  console.log('The response time is:${endTime - startTime}ms`)
})

app.use(async (ctx, next) => {
  console.log('111, the then doSomething')
  await next()
  console.log('111 end')
})

app.use(async (ctx, next) => {
  console.log('222, the then doSomething')
  await next()
  console.log('222 end')
})

app.use(async (ctx, next) => {
  console.log('333, the then doSomething')
  await next()
  console.log('333 end')
})

app.listen(3333, () = > {console.log('server is running at http://localhost:3333')})Copy the code

Take a look at the results:

What happens if you remove next() from the ** ‘222’ ** function?

As you can see, the ** ‘333’ ** middleware does not execute directly. So the order of the middleware has a big impact on the execution of next

Routing koa – the router

We often use koA-Router to handle urls

The installation

npm i koa-router --save
Copy the code

Look at an example:

const Koa = require('koa')
const app = new Koa()
const Router = require('koa-router')

const router = new Router()

router.get('/'.async (ctx, next) => {
  ctx.body = 'Hi, I'm on the index page.'
})

router.get('/user'.async (ctx, next) => {
  ctx.body = 'Hello, I'm on the User page.'
})

router.get('/error'.async (ctx, next) => {
  ctx.body = 'Hello, I have error here.'
})

app.use(router.routes())

app.listen(3333, () = > {console.log('server is running at http://localhost:3333')})Copy the code

The KOA-Router also supports nesting, which is convenient for loading all child routes through a single master route. Look at an example:

const Koa = require('koa')
const app = new Koa()
const Router = require('koa-router')

// Child route 1
let oneRouter = new Router()

oneRouter.get('/'.async (ctx, next) => {
  ctx.body = 'Hello, I'm oneRouter.'
})

// Child route 2
let twoRouter = new Router()

twoRouter.get('/'.async (ctx, next) => {
  ctx.body = 'Hi, I'm on page twoRouter.'
}).get('/home'.async (ctx , next) => {
  ctx.body = 'Hello, I'm on the home page'
})

// Load all child routes
let indexRouter = new Router()

indexRouter.use('/one',oneRouter.routes(), oneRouter.allowedMethods())
indexRouter.use('/two',twoRouter.routes(), twoRouter.allowedMethods())

app
  .use(indexRouter.routes())
  .use(indexRouter.allowedMethods())

app.listen(3333, () = > {console.log('server is running at http://localhost:3333')})Copy the code

Take a look at the results:

Get request data

The Koa-Router provides the common.get.put.post.del interface to handle various requirements. In practice we use get and POST a lot. Let’s take a look at the get example:

const Koa = require('koa')
const app = new Koa()
const Router = require('koa-router')
const router = new Router()

router.get('/data'.async (ctx , next)=> {
  let url = ctx.url

  // Get the data we want from CTX request
  let data = ctx.request.query
  let dataQueryString = ctx.request.querystring

  ctx.body = {
    url,
    data,
    dataQueryString
  }
})

app.use(router.routes())

app.listen(3333, () = > {console.log('server is running at http://localhost:3333')})Copy the code

Type http://localhost:3333/data? in the browser User =wuyanzu&id=123456, you can see the running result

You can see the difference..query returns an object, while.queryString returns a string, which makes sense. (Chrome plugin to display in JSON format)

If RESTful specifications are followed, such as ‘/user/:id’, we can use the following example to retrieve the desired data

Add code

router.get('/data/:id'.async (ctx, next) => {

  // Also get the data we want from CTX, but using params objects
  let data = ctx.params

  ctx.body = data
})
Copy the code

The browser running http://localhost:3333/data/4396 see the result

Let’s look at the post example

The usual request for a POST is to put the data in the body. A very common and useful middleware – Koa-BodyParser is recommended at this point

First installation

npm i koa-bodyparser --save
Copy the code

And then we add it to the code that we just did

router.get('/post'.async (ctx, next) => {
    // Simulate a submission page
  let html = '
      

/>



ctx.body = html }) router.post('/post/result'.async (ctx, next) => { // We can get the submitted data from CTX's request.body let {name, num} = ctx.request.body if (name && num) { ctx.body = 'Hello, the star you most resemble is:${name}The license plate number you know is:${num}` } else { ctx.body = 'Uh-oh! You filled out the wrong information.'}})Copy the code

Take a look at the results

cache

It is very convenient for KOA to manipulate cookies, which are also retrieved from the context CTX.

  • Ctx.cookie. get(name, [options]) reads the cookie in the context request
  • Ctx.cookie. set(name, value, [options]) writes cookies to the context

Add the following to our post request:

router.post('/post/result'.async (ctx, next) => {
  // We can get the submitted data from CTX's request.body
  let {name, num} = ctx.request.body

  if (name && num) {
    ctx.body = 'Hello, the star you most resemble is:${name}The license plate number you know is:${num}`
    ctx.cookies.set(
      'xunleiCode',num,
      {
        domain: 'localhost'.// Write the domain name of the cookie
        path: '/post/result'.// Write the path to the cookie
        maxAge: 10 * 60 * 1000.// Cookie validity period
        expires: new Date('2018-09-17'),  // Cookie expiration time
        httpOnly: false.// Whether to obtain only in HTTP requests
        overwrite: false  // Whether overwriting is allowed})}else {
    ctx.body = 'Uh-oh! You filled out the wrong information.'}})Copy the code

Take a look at the results:

Koa-session: 🌰


const session = require('koa-session')

app.keys = ['some secret hurr'];
const CONFIG = {
  key: 'koa:sess'.//cookie key (default is koa:sess)
  maxAge: 86400000.MaxAge in ms (default is 1 days)
  overwrite: true.// Can overwrite (default default true)
  httpOnly: true.HttpOnly or not (default true)
  signed: true.// Signature defaults to true
  rolling: false.// Forcibly set the cookie on each request, which resets the cookie expiration time (default: false)
  renew: false.//(boolean) renew session when session is nearly expired,
};
app.use(session(CONFIG, app));

Copy the code

summary

When it comes to areas you haven’t touched, I’ve always been a fan of seeing how you play, and then seeing how you “really” play when you know how to play. From the above code and descriptions, we have a general idea of koA and Node. In the next article we will cover middleware splitting, unit testing, logging, management specifications, and more. Let’s grow together!

Spread the word

This article is published in Front of Mint Weekly. Welcome to Watch & Star.

Welcome to the discussion. Give it a thumbs up before we go. ◕ ‿ ◕. ~