blog

Koaのソースコードを学ぶためにあなたと手をつないで - コンテキスト&リクエスト&レスポンス

序文\n\n\nコンテキスト\nソースコードファイルのコンテキストはわずか252行で、非常に単純な、全体のドキュメントを見下ろす型判定、エラー処理に加えて、2つの場所のコアは、クッキーとデリゲート、こ...

Apr 12, 2020 · 4 min. read
シェア

序文

前の記事では、学んだ、リッスンメソッドでカスタムthisを呼び出すことを学びました。".コールバック、コールバック実行の過程でコンテキスト、リクエスト、レスポンスを呼び出し、この記事では、何が行われているかを確認します。

Context

コンテキストのソースコードファイルはわずか252行で、非常にシンプルで、ファイル全体を見下ろす型判定、エラー処理に加えて、2つの場所のコアは、クッキーとデリゲートであり、この記事では、主にこの2つの部分について説明します。

cookies

まずソースコードを見てみましょう。

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;
 }

このコードは主にクッキーを get と set フォームにカプセル化し、またシンボルのユニークな特性によって単一のインスタンスを作成します。 また、Cookies オブジェクトを作成します。Cookies オブジェクトのソースコード:github.com/ScottHamper... は、その主な役割は req オブジェクトを通してヘッダの Cookie オブジェクトを取得することと、res オブジェクトにいくつかの変更を加えることです。主な役割は、reqオブジェクトを通してヘッダのクッキーオブジェクトを取得することと、resオブジェクトにいくつかの変更を加えることです。

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');

デリゲートの役割は、リクエストとレスポンスのメソッドとプロパティをContextに 委譲 することです。 まず、上のコードを縮小してみましょう:

delegate(proto, 'response')
 .method('attachment')
 .access('status')
 .getter('headerSent')

主にメソッド、アクセス、ゲッターの3つのメソッドと呼ばれる、デリゲートが実際に何をするかを確認するには、デリゲートのソースコードを見つけるには、まず、メソッドを見てください。

function Delegator(proto, target) {
 if (!(this instanceof Delegator)) return new Delegator(proto, target);
 
 // 
    1.  プロトとターゲットを取得する
 this.proto = proto;
 this.target = target;
 
 // 
    2.  メソッド、ゲッター、セッター、フルエント配列を作成する
 this.methods = [];
 this.getters = [];
 this.setters = [];
 this.fluents = [];
}
Delegator.prototype.method = function(name){
 var proto = this.proto;
 var target = this.target;
 
 // 
    3.  は、メソッド名プッシュメソッドの配列に渡される
 this.methods.push(name);
 // プロトがメソッドを呼び出すときに、直接プロトを呼び出すことができるように、プロトに着信メソッド名をマウントする。[target] 
 proto[name] = function(){
 return this[target][name].apply(this[target], arguments);
 };
 return this;
};

デリゲータ関数とメソッドのメソッドを呼び出すと、主に以下の4つのことが行われます。

  • 1. プロトとターゲットを取得
  • 2. メソッド、ゲッター、セッター、フルエント配列を作成します。
  • メソッド名をメソッド配列に入れます。
  • プロトがメソッドを呼び出すときに、プロト[target]のメソッドを直接呼び出せるように、入力されたメソッド名をプロトにマウントします。

ゲッターとアクセスについてもう一度

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);
};

ゲッターメソッドは、CTX上でリクエストのプロパティを直接呼び出す機能を実装しています。 セッターメソッドは、CTX上でリクエストのプロパティを変更する機能を実装しています。

koa は Delegator パターンを使って、リクエストとレスポンスで ctx がメソッドやプロパティを簡単に呼び出せるようにしています。

request&&response

要約

関連記事

ハンズオンで学ぶKoaソースコード - ディレクトリ構造 ハンズオンで学ぶKoaソースコード - ディレクトリ構造ハンズオンで学ぶKoaソースコード -ディレクトリ構造アプリケーション

Read next

これを読んで、ブラウザのキャッシュについて他にどんな質問がある?

ウェブシステム全体がHTTPプロトコルの上に構築されており、HTTPキャッシュメカニズムを使用することで、サーバーの負荷が大幅に軽減されるだけでなく、より重要なのはページの読み込みが高速化され、ユーザーのトラフィック消費が抑えられることです。 高速な到達性とアクセスのしやすさはウェブ固有の特徴であり、そのキャッシュ機構は、サーバーやブラウザのベンダーによって、手段として広く実装されています...

Apr 12, 2020 · 6 min read