preface
The main content of this article is to learn koA’s source code with others by describing the author’s own process of learning koA’s source code. Koa was designed to be a smaller, more expressive, and more robust cornerstone of Web application and API development. Because of its high scalability, koA’s source code is relatively easy to read. If you follow my article to learn, it must be my bad writing.
In the listen method, a custom this.callback is called. Context, Request, and Response are called during callback execution, and this article looks at what is done.
Context
The source file for Context is only 252 lines, which is very simple. In addition to type judgment and error handling, the two most core parts of the file are cookies and delegates. This article focuses on these two parts.
cookies
Take a look at the relevant source code
const COOKIES = Symbol('context#cookies');
const Cookies = require('cookies');
get cookies() {
if(! this[COOKIES]) { this[COOKIES] = new Cookies(this.req, this.res, { keys: this.app.keys, secure: this.request.secure }); } return this[COOKIES]; }, set cookies(_cookies) { this[COOKIES] = _cookies; } Copy the code
This code is mainly to encapsulate cookies into get, set form at the same time through the unique feature of symbol to create a singleton (this writing method is also very common and easy to use, recommend everyone to use in their own code) at the same time to create cookies, cookies object source address: Github.com/ScottHamper… , the main function is to get the cookie object in the header through the REQ object, as well as some changes to the RES object, we can see the source code and usage.
delegate
/ * * * Response delegation.
* /
delegate(proto, 'response')
.method('attachment') .method('redirect') .method('remove') .method('vary') .method('has') .method('set') .method('append') .method('flushHeaders') .access('status') .access('message') .access('body') .access('length') .access('type') .access('lastModified') .access('etag') .getter('headerSent') .getter('writable'); / * * * Request delegation. * / delegate(proto, 'request') .method('acceptsLanguages') .method('acceptsEncodings') .method('acceptsCharsets') .method('accepts') .method('get') .method('is') .access('querystring') .access('idempotent') .access('socket') .access('search') .access('method') .access('query') .access('path') .access('url') .access('accept') .getter('origin') .getter('href') .getter('subdomains') .getter('protocol') .getter('host') .getter('hostname') .getter('URL') .getter('header') .getter('headers') .getter('secure') .getter('stale') .getter('fresh') .getter('ips') .getter('ip'); Copy the code
Delegate delegates methods and properties on request and response to Context. Let’s cut this down a bit:
delegate(proto, 'response')
.method('attachment')
.access('status')
.getter('headerSent')
Copy the code
There are three methods called: Method, Access, and getter. Let’s see what delegate does. Find the delegate source
function Delegator(proto, target) {
if(! (this instanceof Delegator))return new Delegator(proto, target);
// ① Get proto and target this.proto = proto;
this.target = target; // create methods, getters, setters, fluents array this.methods = []; this.getters = []; this.setters = []; this.fluents = []; } Delegator.prototype.method = function(name){ var proto = this.proto; var target = this.target; // ③ Push the passed method name into the methods array this.methods.push(name); // mount the name of the passed method to proTO so that proTO can call the method of proto[target] directly proto[name] = function() { return this[target][name].apply(this[target], arguments); }; return this; }; Copy the code
The method calling the delegator function and method basically does four things
- Get proto (context) and target (‘request’ or ‘esponse’ in KOA)
- ② Create methods, getters, setters, fluents array
- ③ Push the passed method name into the methods array
- (4) Mount the name of the passed method to proTO so that proTO can call the method of proTO [target] directly
Let’s look at getter and access again
Delegator.prototype.getter = function(name){
var proto = this.proto;
var target = this.target;
this.getters.push(name);
proto.__defineGetter__(name, function() { return this[target][name]; }); return this; }; Delegator.prototype.setter = function(name){ var proto = this.proto; var target = this.target; this.setters.push(name); proto.__defineSetter__(name, function(val){ return this[target][name] = val; }); return this; }; Delegator.prototype.access = function(name){ return this.getter(name).setter(name); }; Copy the code
A getter method implementation is a property that can be invoked directly on CTX (for example, Ctx.host === ctx.request.host) setters allow you to modify the properties of the request on CTX. Access mounts both getter and setter methods
Koa uses the Delegator pattern to make it easy for CTX to call methods and attributes on request and Response.
request&&response
Request and Response objects are essentially nothing special, and KOA encapsulates common methods and properties into two objects. The code of the two files adds up to a total of more than 1000 lines, and more than half of them are comments. I suggest that these two files simply have a look, and when needed, they can be checked as documents without further details.
conclusion
Koa source code we first analysis to here, this article is completely in accordance with the author of their own learning source code process to describe, the writing is not good to read it may have a little running account, but the author will try to describe clearly, and read the source code of some methods and skills to share, please collect points like support.
Related articles
Handy with you learn Koa source (a) – directory structure to learn with you holding Koa source (a) – directory structure to learn with you holding Koa source (2) — Appilication
This article is formatted using MDNICE