preface
- We use HTTP, FS and other modules directly to build a simple server is not a big problem, but when the business logic is more and more troublesome, our own code will be more and more, more and more trouble, repeatability is also high
- At this time, we will be very comfortable to use the framework. The framework will not add functions for us, but provide us with the encapsulation and arrangement of our business in accordance with certain rules, so that we can use it easily and conveniently
- The mainstream frameworks used by Node webServer include Express and Koa
- Express has a lot of built-in middleware, which is highly integrated and easy to use
- Koa is lightweight, compact and easy to customize
- Let’s take a look at Koa
Introduction to the
- Koa was built by the original Express team to be a smaller, more expressive, and more robust Web framework. Composing web applications using KOA eliminates repetitive and tedious nesting of callback functions and greatly improves error handling efficiency by combining different generators. Koa doesn’t bundle any middleware into kernel methods, it just provides a lightweight and elegant library of functions that makes writing Web applications a breeze
- The main job of a Webserver is to parse the request -> process the response, and Koa encapsulates the basic logic of both and provides interfaces to extend them
The installation
- Koa requires Node V7.6.0 or later to support ES2015, asynchronous methods
npm install koa
Copy the code
Implementing the first server with Koa (simple use)
- A Koa application is an object that contains a set of middleware Generator functions. These middleware functions are organized in a stack-like structure and executed sequentially based on request requests
- The core design idea of Koa is to provide high-level syntactic sugar encapsulation for the middleware layer to enhance its interoperability and robustness, and to make writing middleware a lot more fun
// Reference the Koa framework
const Koa = require('koa');
// Instantiate an app object
const app = new Koa();
// KoA uses the use syntax for the middle key
app.use(ctx= > {
// ctx.body equals http.createserver ((req, res) => {res.end('hello world')});
ctx.body = 'hello world'
});
// equivalent to http.createserver ().listen
app.listen(8080)
Copy the code
- As you can see, Koa actually uses the HTTP module, just wrapped around it, and the middle key can do a whole bunch of things for us
Intermediate key middleware
- App.use () is used to register middleware and must be a generator function
- Koa’s middleware cascades in a more traditional way, eliminating the complex code logic of node’s frequent callbacks
- Koa will put a bunch of middle key functions into a chain, and each middle key function can do its own thing, and then use
next()
To call the next middle key function - The intermediate key must be a function that can be asynchronous: handled with async and await in ES7
- Use internally encapsulates two objects:
- ctx
- next
next
- Next is the next function koA passes in to process
- The next function is not executed unless next is called
- You can think of him as a routing guard in Vue
- When the yield Next statement is executed, Koa suspends the middleware and continues to execute the next middleware that meets the request, and control is returned to the upper middleware step by step
app.use((ctx, next) = > {
next();
console.log(1);
});
app.use((ctx, next) = > {
console.log(2);
next();
});
app.use((ctx, next) = > {
console.log(3);
ctx.body = 'hello world'
});
// Next () is not executed
app.use((ctx, next) = > {
console.log(4);
});
// 2 -> 3 -> 1
Copy the code
ctx(Koa Context):
- He put the node
request
和response
Objects are wrapped in a single object, which provides many useful methods for writing Web applications and apis - CTX objects include:
- Request object of a req-node
- Response object of res-node
- Request-koa’s request object
- Response-koa’s Response object
- ctx.body
- Return to the body
- With CTX. Response. The body is equal
- Ctx. status: Sets the status code
- Ctx. url: obtains the request URL
- Ctx. header: header information
- .
koa-router
- In practice, it is impossible to have only one interface. In this case, route management is needed. We can easily process routes with koA-Router
- Routing is the management of a URL associated with a function
- All the KOA-router does is match the URL and execute the corresponding function that we registered
The installation
npm install koa-router
Copy the code
new KoaRouter()
- Instance object of the KOa-Router
- Object contains get, POST and other methods to respond to different requests
- Each method takes two arguments:
- Registered route
- The callback function
- This function also acts as an intermediate key
const Koa = require('koa');
const app = new Koa();
Koa / / in the router
const KoaRouter = require('koa-router');
// Instantiate a routing object
const router = new KoaRouter();
Req. url === '/'
router.get('/'.ctx= > {
ctx.body = 'hello world'
});
router.get('/test'.ctx= > {
ctx.body = 'test'
});
Copy the code
router.routes()
- Router. routes returns a middle key function
- This intermediate key function analyzes the URL and matches the analyzed URL with the registered URL. If the match is successful, the corresponding registration function is executed
const routerMiddleware = router.routes();
app.use(routerMiddleware);
app.listen(8080);
Copy the code
- New KoaRouter() + router.routes() is a complete example
koa-static-cache
npm install koa-static-cache
The installation- It is an intermediate key that deals exclusively with static resources
- He can map our static resources
- StaticCache takes three parameters (dir[, options][, files]) :
- Dir: indicates the directory to be mapped
- Options: Optional configuration items
options.dir
: Mapping directory (priority lower thandir
)options.maxAge
: Maximum duration of file cache control (default: 0)options.cacheControl
: Optional cache control header (overridesoptions.maxAge
)options.buffer
: (bool) Stores files in memory instead of streaming from the file system on each requestoptions.gzip
: (bool) When requestedaccept-encoding
When gzip is included, the file is compressed by gzipoptions.usePrecompiledGzip
: (bool) Try to use gzip file loaded from diskoptions.alias
: Object map of aliases (obj: enables files to have aliases)options.prefix
: URL prefix replacementoptions.dynamic
: (bool) Dynamically loading files (istrue
Is monitored when files are added or deleted.options.filter
: Filters files in directories (if array is set – only files are allowed to be listed)options.preload
: (bool) Indicates whether to cache assets during initialization. Default value: bool Indicates whether to cache assets during initializationtrue
, such asoptions.dynamic
为true
, he also fortrue
options.files
And:files
The same
- Files: Optional configuration of individual files (best used here
path.normalize
Standardize the address, otherwise you may not find the object)
const Koa = require('koa');
const app = new Koa();
const path = require('path');
/ / reference koa - static - cache
const KoaStaticCache = require('koa-static-cache');
const files = {}
// The request maps files in the./static directory
app.use(KoaStaticCache('./static', {
// Set the URL prefix /css. CSS => /public/css.css
prefix: '/public'.gzip: true.dynamic: true
}, files));
// If multiple directories need to be mapped, use is unnecessary
KoaStaticCache('/public', {})
// Set file handling separately
files[path.normalize('/public/css.css')].maxAge = 365 * 24 * 60 * 60;
app.listen(8080);
Copy the code
Encapsulate the Koa intermediate key yourself
- The middle key must be a function
- Through the use of
- The CommonJS specification can make logic more readable (modularity)
- The following example is a simple imitation
koa-static-cache
Point mapping function of
const Koa = require('koa');
const app = new Koa();
const fs = require('fs');
const path = require('path');
function myStatic(dir) {
// Return an intermediate key function to pass dir
return (ctx, next) = > {
// Read the files in the directory
const files = fs.readdirSync(dir);
// Check whether the request is a file in the directory.
if (files.map(item= > '/' + item).indexOf(ctx.url) > -1) {
// The header information needs to be written as required
ctx.set('Content-Type'.'text/plain; charset=utf-8');
ctx.body = fs.readFileSync(path.join(dir + ctx.url));
} else {
ctx.body = "Not Find";
}
}
}
app.use(myStatic('./static'));
app.listen(8080);
Copy the code