Koa.js-クイックガイド

Webアプリケーションフレームワークは、Webサイト、Webアプリ、およびバックエンドを構築するための単純なAPIを提供します。低レベルのプロトコルやプロセスなどについて心配する必要はありません。

コアとは?

Koaは、アプリケーションを構築するための最小限のインターフェースを提供します。これは非常に小さなフレームワーク(600 LoC)であり、アプリの構築に必要なツールを提供し、非常に柔軟性があります。Koaのnpmには多数のモジュールがあり、直接プラグインできます。Koaは、すべてのベルやホイッスルのないexpress.jsのコアと考えることができます。

なぜコア?

Koaはフットプリントが小さく(600 LoC)、サーバー側のアプリを作成するためのノード上の非常に薄い抽象化レイヤーです。完全にプラグイン可能で、巨大なコミュニティがあります。これにより、Koaを簡単に拡張して、必要に応じて使用することもできます。エクスプレスなどの古いフレームワークよりも優れた最先端テクノロジー(ES6)を使用して構築されています。

パグ

Pug(以前はJadeとして知られていました)は、HTMLテンプレートを作成するための簡潔な言語です。

  • HTMLを生成します
  • 動的コードをサポート
  • 再利用性(DRY)をサポート

これは、コアで使用される最も人気のあるテンプレート言語の1つです。

MongoDBとMongoose

MongoDBは、開発とスケーリングを容易にするために設計されたオープンソースのドキュメントデータベースです。このデータベースを使用してデータを保存します。

Mongooseはnode.jsのクライアントAPIであり、Koaアプリケーションからデータベースに簡単にアクセスできます。

Koaフレームワークを使用した開発を開始するには、Nodeとnpm(ノードパッケージマネージャー)をインストールする必要があります。これらをまだお持ちでない場合は、ノードのセットアップに進んで、ローカルシステムにノードをインストールしてください。ターミナルで次のコマンドを実行して、nodeとnpmがインストールされていることを確認します。

$ node --version
$ npm --version

−のような出力を受け取るはずです。

v5.0.0
3.5.2

ノードのバージョンが6.5.0より上であることを確認してください。Nodeとnpmが設定されたので、npmとは何かとその使用方法を理解しましょう。

ノードパッケージマネージャー(npm)

npmはノードのパッケージマネージャーです。npmレジストリは、Node.js、フロントエンドWebアプリ、モバイルアプリ、ロボット、ルーター、およびJavaScriptコミュニティの他の無数のニーズに対応するオープンソースコードのパッケージのパブリックコレクションです。npmを使用すると、これらすべてのパッケージにアクセスしてローカルにインストールできます。npmJSのnpmで利用可能なパッケージのリストを参照できます。

npmの使い方は?

npmを使用してパッケージをインストールする方法は、グローバルとローカルの2つです。

Globally−この方法は通常、開発ツールとCLIベースのパッケージをインストールするために使用されます。パッケージをグローバルにインストールするには、次のコマンドを使用します。

$ npm install -g <package-name>

Locally−この方法は通常、フレームワークとライブラリをインストールするために使用されます。ローカルにインストールされたパッケージは、インストールされているディレクトリ内でのみ使用できます。パッケージをローカルにインストールするには、上記と同じコマンドを-なしで使用します。g 国旗。

$ npm install <package-name>

npmを使用してプロジェクトを作成するときは常に、プロジェクトに関するすべての詳細を含むpackage.jsonファイルを提供する必要があります。npmを使用すると、このファイルを簡単に設定できます。開発プロジェクトを立ち上げましょう。

Step 1 − terminal / cmdを起動し、hello-worldという名前の新しいフォルダーを作成して、そこにcdします。

Step 2 − npmを使用してpackage.jsonファイルを作成するには、以下を使用します。

npm init

以下の情報をお伺いします−

Enterキーを押し続け、「作成者名」フィールドに自分の名前を入力します。

Step 3− package.jsonファイルが設定されたので、Koaをインストールします。Koaをインストールしてpackage.jsonファイルに追加するには、次のコマンドを使用します。

$ npm install --save koa

Koaが正しくインストールされていることを確認するには、次のコマンドを実行します。

$ ls node_modules #(dir node_modules for windows)

Tip--save フラグは次のように置き換えることができます -S国旗。このフラグは、Koaがpackage.jsonファイルへの依存関係として追加されることを保証します。これには利点があります。次にプロジェクトのすべての依存関係をインストールする必要があるときは、コマンドnpm installを実行するだけで、このファイルで依存関係が検出され、インストールされます。

Koaフレームワークを使用して開発を開始するために必要なのはこれだけです。開発プロセスをはるかに簡単にするために、npm、nodemonからツールをインストールします。このツールの機能は、ファイルに変更を加えるとすぐにサーバーを再起動することです。それ以外の場合は、ファイルを変更するたびにサーバーを手動で再起動する必要があります。nodemonをインストールするには、次のコマンドを使用します。

$ npm install -g nodemon

これで、コアに飛び込む準備が整いました。

開発を設定したら、Koaを使用して最初のアプリの開発を開始します。と呼ばれる新しいファイルを作成しますapp.js 次のように入力します。

var koa = require('koa');
var app = new koa();

app.use(function* (){
   this.body = 'Hello world!';
});

app.listen(3000, function(){
   console.log('Server running on https://localhost:3000')
});

ファイルを保存し、ターミナルに移動して入力します。

$ nodemon app.js

これにより、サーバーが起動します。このアプリをテストするには、ブラウザを開いてに移動しますhttps://localhost:3000 次のメッセージが表示されます。

このアプリはどのように機能しますか?

最初の行は、ファイルにKoaをインポートします。変数Koaを介してそのAPIにアクセスできます。これを使用してアプリケーションを作成し、varappに割り当てます。

app.use(function)−この関数はミドルウェアであり、サーバーがリクエストを受け取るたびに呼び出されます。ミドルウェアについては、次の章で詳しく説明します。コールバック関数はジェネレーターであり、次の章で説明します。このジェネレーターのコンテキストは、コアではコンテキストと呼ばれます。このコンテキストは、要求オブジェクトと応答オブジェクトにアクセスして変更するために使用されます。この応答の本文を次のように設定していますHello world!

app.listen(port, function)−この関数は、指定されたポートで接続をバインドしてリッスンします。ここで必要なパラメータはポートだけです。アプリが正常に実行されると、コールバック関数が実行されます。

JavaScript ES6の最もエキサイティングな新機能の1つは、ジェネレーターと呼ばれる新しい種類の関数です。ジェネレーターの前は、スクリプト全体が通常は上から下の順序で実行され、コードの実行を停止して後で同じスタックで再開する簡単な方法はありませんでした。ジェネレーターは、終了して後で再入力できる関数です。それらのコンテキスト(変数バインディング)は、再入力間で保存されます。

ジェネレーターを使用すると、その間にコードの実行を停止できます。したがって、簡単なジェネレーターを見てみましょう。

var generator_func = function* (){
   yield 1;
   yield 2;
};

var itr = generator_func();
console.log(itr.next());
console.log(itr.next());
console.log(itr.next());

上記のコードを実行すると、次のようになります。

{ value: 1, done: false }
{ value: 2, done: false }
{ value: undefined, done: true }

上記のコードの内部を見てみましょう。まず、と呼ばれるジェネレータを作成しますgenerator_func()。この奇妙な外観の関数のインスタンスを作成し、に割り当てましたitr。それから私たちは電話をかけ始めましたnext() このitr変数で。

next()を呼び出すと、ジェネレーターが起動し、yieldに達するまで実行されます。次に、値と完了を含むオブジェクトを返します。値には式の値があります。この式は何でもかまいません。この時点で、実行を一時停止します。この関数(next)を呼び出すと、ジェネレーターは最後の降伏点から実行を再開し、関数の状態は一時停止時と同じで、次の降伏点まで続きます。これは、コードにイールドポイントがなくなるまで行われます。

コアの発電機

では、なぜこのチュートリアルでジェネレータについて説明しているのでしょうか。hello worldプログラムから覚えているかもしれませんが、私たちはfunction* ()app.use()にコールバックを渡す表記。Koaはオブジェクトであり、ミドルウェアジェネレーター関数の配列が含まれています。これらの関数はすべて、要求ごとにスタックのように構成および実行されます。Koaは、制御フローのダウンストリームとそれに続くアップストリームも実装します。

これをよりよく理解するには、次の例を見てください。

var koa = require('koa');
var app = koa();
 
app.use(function* (next) {
   //do something before yielding to next generator function 
   
   //in line which will be 1st event in downstream
   console.log("1");
   yield next;
 
   //do something when the execution returns upstream, 
   //this will be last event in upstream
   console.log("2");
});
app.use(function* (next) {
   // This shall be 2nd event downstream
   console.log("3");
   yield next;
 
   // This would be 2nd event upstream
   console.log("4");
});
app.use(function* () { 
   // Here it would be last function downstream
   console.log("5");
   
   // Set response body
   this.body = "Hello Generators";

   // First event of upstream (from the last to first)
   console.log("6");
});

app.listen(3000);

上記のコードを実行してに移動するとき https://localhost:3000/ コンソールに次の出力が表示されます。

1
3
5
6
4
2

これは基本的に、Koaがジェネレーターを使用する方法です。これにより、このプロパティを使用してコンパクトなミドルウェアを作成し、アップストリーム機能とダウンストリーム機能の両方のコードを記述できるため、コールバックから解放されます。

Webフレームワークは、HTMLページ、スクリプト、画像などのリソースをさまざまなルートで提供します。Koaはコアモジュールのルートをサポートしていません。Koaでルートを簡単に作成するには、Koa-routerモジュールを使用する必要があります。次のコマンドを使用して、このモジュールをインストールします。

npm install --save koa-router

Koa-routerがインストールされたので、簡単なGETルートの例を見てみましょう。

var koa = require('koa');
var router = require('koa-router');
var app = koa();

var _ = router();              //Instantiate the router
_.get('/hello', getMessage);   // Define routes

function *getMessage() {
   this.body = "Hello world!";
};

app.use(_.routes());           //Use the routes defined using the router
app.listen(3000);

アプリケーションを実行してlocalhost:3000 / helloに移動すると、サーバーはルート「/ hello」でgetリクエストを受信します。Koaアプリは、このルートにアタッチされたコールバック関数を実行し、「HelloWorld!」を送信します。応答として。

同じルートで複数の異なる方法を使用することもできます。例えば、

var koa = require('koa');
var router = require('koa-router');
var app = koa();

var _ = router(); //Instantiate the router

_.get('/hello', getMessage);
_.post('/hello', postMessage);

function *getMessage() {
	this.body = "Hello world!";
};
function *postMessage() {
   this.body = "You just called the post method at '/hello'!\n";
};
app.use(_.routes()); //Use the routes defined using the router
app.listen(3000);

このリクエストをテストするには、ターミナルを開き、cURLを使用して次のリクエストを実行します

curl -X POST "https://localhost:3000/hello"

特別な方法、 allは、同じ関数を使用して特定のルートですべてのタイプのhttpメソッドを処理するためにexpressによって提供されます。この方法を使用するには、次のことを試してください。

_.all('/test', allMessage);

function *allMessage(){
   this.body = "All HTTP calls regardless of the verb will get this response";
};

これでルートを定義できます。それらは静的または固定のいずれかです。動的ルートを使用するには、さまざまなタイプのルートを提供する必要があります。動的ルートを使用すると、パラメーターを渡し、それに基づいて処理することができます。以下は、動的ルートの例です。

var koa = require('koa');
var router = require('koa-router');
var app = koa();

var _ = router();

_.get('/:id', sendID);

function *sendID() {
   this.body = 'The id you specified is ' + this.params.id;
}

app.use(_.routes());
app.listen(3000);

これをテストするには、 https://localhost:3000/123。次の応答が返されます。

URLの「123」を他のものに置き換えることができ、それが応答に反映されます。以下は、上記の複雑な例です。

var koa = require('koa');
var router = require('koa-router');
var app = koa();

var _ = router();

_.get('/things/:name/:id', sendIdAndName);

function *sendIdAndName(){
   this.body = 'id: ' + this.params.id + ' and name: ' + this.params.name;
};

app.use(_.routes());

app.listen(3000);

これをテストするには、 https://localhost:3000/things/tutorialspoint/12345

あなたは使用することができます this.paramsURLで渡すすべてのパラメータにアクセスするためのオブジェクト。上記の2つは異なるパスを持っていることに注意してください。それらは決して重複しません。また、「/ things」を取得したときにコードを実行する場合は、個別に定義する必要があります。

パターン一致ルート

正規表現を使用して、URLパラメータの一致を制限することもできます。IDが5桁の長さの数字である必要があるとしましょう。次のルート定義を使用できます。

var koa = require('koa');
var router = require('koa-router');
var app = koa();

var _ = router();

_.get('/things/:id([0-9]{5})', sendID);

function *sendID(){
   this.body = 'id: ' + this.params.id;
}

app.use(_.routes());
app.listen(3000);

これは only5桁の長いIDを持つリクエストに一致します。より複雑な正規表現を使用して、ルートを照合/検証できます。どのルートもリクエストに一致しない場合、応答として「見つかりません」というメッセージが表示されます。

たとえば、上記と同じルートを定義した場合、有効なURLでリクエストすると、次のようになります。

HTTPメソッドはリクエストで提供され、クライアントがリクエストした操作を指定します。次の表は、一般的に使用されるHTTPメソッドをまとめたものです。

シニア番号 方法と説明
1

GET

GETメソッドは、指定されたリソースの表現を要求します。GETを使用したリクエストは、データを取得するだけで、他の効果はありません。

2

POST

POSTメソッドは、サーバーがリクエストに含まれるデータをURIで識別されるリソースの新しいオブジェクト/エンティティとして受け入れることを要求します。

3

PUT

PUTメソッドは、URIで識別される既存のオブジェクトへの変更として、要求に含まれるデータをサーバーが受け入れることを要求します。存在しない場合は、PUTメソッドで作成する必要があります。

4

DELETE

DELETEメソッドは、サーバーが指定されたリソースを削除することを要求します。

これらは最も一般的なHTTPメソッドです。それらの詳細については、https://www.tutorialspoint.com/http/http_methods.htm。

Koa Requestオブジェクトは、ノードのバニラリクエストオブジェクトを抽象化したものであり、日常のHTTPサーバー開発に役立つ追加機能を提供します。Koaリクエストオブジェクトはコンテキストオブジェクトに埋め込まれています。this。リクエストを受け取ったら、リクエストオブジェクトをログアウトしましょう。

var koa = require('koa');
var router = require('koa-router');
var app = koa();

var _ = router();

_.get('/hello', getMessage);

function *getMessage(){
   console.log(this.request);
   this.body = 'Your request has been logged.';
}
app.use(_.routes());
app.listen(3000);

このコードを実行してに移動すると https://localhost:3000/hello、その後、次の応答を受け取ります。

コンソールで、リクエストオブジェクトがログアウトされます。

{ 
   method: 'GET',
   url: '/hello/',
   header: 
   { 
      host: 'localhost:3000',
      connection: 'keep-alive',
      'upgrade-insecure-requests': '1',
      'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) 
         AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36',
      accept: 'text/html,application/xhtml+xml,
         application/xml;q = 0.9,image/webp,*/*;q = 0.8',
      dnt: '1',
      'accept-encoding': 'gzip, deflate, sdch',
      'accept-language': 'en-US,en;q = 0.8' 
   }
}

このオブジェクトを使用して、リクエストの多くの便利なプロパティにアクセスできます。いくつかの例を見てみましょう。

request.header

すべてのリクエストヘッダーを提供します。

request.method

リクエストメソッド(GET、POSTなど)を提供します

request.href

完全なリクエストURLを提供します。

request.path

リクエストのパスを提供します。クエリ文字列とベースURLなし。

request.query

解析されたクエリ文字列を提供します。たとえば、次のようなリクエストでこれをログに記録すると、https://localhost:3000/hello/?name=Ayush&age=20&country=India、次に次のオブジェクトを取得します。

{
   name: 'Ayush',
   age: '20',
   country: 'India'
}

request.accepts(type)

この関数は、要求されたリソースが指定された要求タイプを受け入れるかどうかに基づいて、trueまたはfalseを返します。

あなたはでドキュメント内の要求オブジェクトの詳細を読むことができます要求。

Koa Responseオブジェクトは、ノードのバニラ応答オブジェクトを抽象化したものであり、日常のHTTPサーバー開発に役立つ追加機能を提供します。Koa応答オブジェクトはコンテキストオブジェクトに埋め込まれています。this。リクエストを受け取ったら、レスポンスオブジェクトをログアウトしましょう。

var koa = require('koa');
var router = require('koa-router');
var app = koa();

var _ = router();

_.get('/hello', getMessage);

function *getMessage(){
   this.body = 'Your request has been logged.';
   console.log(this.response);
}

app.use(_.routes());
app.listen(3000);

このコードを実行してに移動すると https://localhost:3000/hello その後、次の応答を受け取ります。

コンソールで、リクエストオブジェクトがログアウトされます。

{ 
   status: 200,
   message: 'OK',
   header: 
   {
      'content-type': 'text/plain; charset=utf-8',
      'content-length': '12' 
   },
   body: 'Your request has been logged.' 
}

ステータスとメッセージはKoaによって自動的に設定されますが、私たちが変更することができます。応答本文を設定しない場合、ステータスコードは404に設定されます。応答本文を設定すると、デフォルトでステータスは200に設定されます。この動作を明示的にオーバーライドできます。

このオブジェクトを使用して、応答の多くの便利なプロパティにアクセスできます。いくつかの例を見てみましょう-

response.header

すべての応答ヘッダーを提供します。

response.status

応答ステータス(200、404、500など)を提供します。このプロパティは、応答ステータスの設定にも使用されます。

response.message

応答メッセージを提供します。このプロパティは、応答付きのカスタムメッセージを設定するためにも使用されます。これはresponse.statusに関連付けられています。

response.body

応答本文を取得または設定します。通常、コンテキストオブジェクトを使用してアクセスします。これは、それにアクセスするためのもう1つの方法です。本文のタイプは、String、Buffer、Stream、Object、またはNullです。

response.type

現在の応答のコンテンツタイプを取得または設定します。

response.get(field)

この関数は、大文字と小文字を区別しない値フィールドを持つヘッダーの値を取得するために使用されます。

response.set(field、value)

この関数は、フィールドと値のペアを使用して応答にヘッダーを設定するために使用されます。

response.remove(field)

この関数は、フィールド名を使用して応答のヘッダーの設定を解除するために使用されます。

応答オブジェクトの詳細については、Responseのドキュメントをご覧ください。

Webサイトを作成するときは、リダイレクトが非常に重要です。不正な形式のURLが要求された場合、またはサーバーにエラーがある場合は、それぞれのエラーページにリダイレクトする必要があります。リダイレクトを使用して、Webサイトの制限された領域にユーザーを近づけないようにすることもできます。

エラーページを作成し、誰かが不正な形式のURLを要求するたびにそのページにリダイレクトしましょう。

var koa = require('koa');
var router = require('koa-router');
var app = koa();
var _ = router();

_.get('/not_found', printErrorMessage);
_.get('/hello', printHelloMessage);

app.use(_.routes());
app.use(handle404Errors);

function *printErrorMessage() {
   this.status = 404;
   this.body = "Sorry we do not have this resource.";
}
function *printHelloMessage() {
   this.status = 200;
   this.body = "Hey there!";
}
function *handle404Errors(next) {
   if (404 != this.status) return;
   this.redirect('/not_found');
}
app.listen(3000);

このコードを実行して/ hello以外のルートに移動すると、/ not_foundにリダイレクトされます。最後にミドルウェアを配置しました(このミドルウェアへのapp.use関数呼び出し)。これにより、最終的にミドルウェアに到達し、対応する応答を送信することが保証されます。上記のコードを実行したときに表示される結果は次のとおりです。

に移動するとき https://localhost:3000/hello、取得-

他のルートに移動すると、次のようになります。

エラー処理は、Webアプリケーションの構築において重要な役割を果たします。Koaはこの目的にもミドルウェアを使用しています。

Koaでは、ミドルウェアを追加します。 try { yield next }最初のミドルウェアの1つとして。ダウンストリームでエラーが発生した場合は、関連するcatch句に戻り、ここでエラーを処理します。例-

var koa = require('koa');
var app = koa();

//Error handling middleware
app.use(function *(next) {
   try {
      yield next;
   } catch (err) {
      this.status = err.status || 500;
      this.body = err.message;
      this.app.emit('error', err, this);
   }
});

//Create an error in the next middleware
//Set the error message and status code and throw it using context object

app.use(function *(next) {
   //This will set status and message
   this.throw('Error Message', 500);
});

app.listen(3000);

上記のコードで意図的にエラーを作成し、最初のミドルウェアのcatchブロックでエラーを処理しています。次に、これはコンソールに送信されるだけでなく、クライアントへの応答として送信されます。以下は、このエラーをトリガーしたときに表示されるエラーメッセージです。

InternalServerError: Error Message
   at Object.module.exports.throw 
      (/home/ayushgp/learning/koa.js/node_modules/koa/lib/context.js:91:23)
   at Object.<anonymous> (/home/ayushgp/learning/koa.js/error.js:18:13)
   at next (native)
   at onFulfilled (/home/ayushgp/learning/koa.js/node_modules/co/index.js:65:19)
   at /home/ayushgp/learning/koa.js/node_modules/co/index.js:54:5
   at Object.co (/home/ayushgp/learning/koa.js/node_modules/co/index.js:50:10)
   at Object.toPromise (/home/ayushgp/learning/koa.js/node_modules/co/index.js:118:63)
   at next (/home/ayushgp/learning/koa.js/node_modules/co/index.js:99:29)
   at onFulfilled (/home/ayushgp/learning/koa.js/node_modules/co/index.js:69:7)
   at /home/ayushgp/learning/koa.js/node_modules/co/index.js:54:5

現在、サーバーに送信されたリクエストはすべてこのエラーになります。

ミドルウェア機能は、にアクセスできる機能です。 context objectそして、アプリケーションの要求/応答サイクルの次のミドルウェア機能。これらの関数は、リクエストボディの解析、レスポンスヘッダーの追加などのタスクのリクエストオブジェクトとレスポンスオブジェクトを変更するために使用されます。Koaは、次のようにさらに一歩進んでいます。'downstream'、次にコントロールを逆流させます 'upstream'。この効果はと呼ばれますcascading

以下は、動作中のミドルウェア関数の簡単な例です。

var koa = require('koa');
var app = koa();
var _ = router();

//Simple request time logger
app.use(function* (next) {
   console.log("A new request received at " + Date.now());
   
   //This function call is very important. It tells that more processing is 
   //required for the current request and is in the next middleware function/route handler.
   yield next;
});

app.listen(3000);

上記のミドルウェアは、サーバー上のすべての要求に対して呼び出されます。したがって、すべてのリクエストの後に、コンソールに次のメッセージが表示されます。

A new request received at 1467267512545

特定のルート(およびそのすべてのサブルート)に制限するには、ルーティングの場合と同じようにルートを作成する必要があります。実際、これらのミドルウェアは、私たちの要求を処理するだけです。

例えば、

var koa = require('koa');
var router = require('koa-router');
var app = koa();

var _ = router();

//Simple request time logger
_.get('/request/*', function* (next) {
   console.log("A new request received at " + Date.now());
   yield next;
});

app.use(_.routes());
app.listen(3000);

これで、「/ request」のサブルートをリクエストするたびに、時刻がログに記録されます。

ミドルウェア呼び出しの順序

Koaのミドルウェアで最も重要なことの1つは、ミドルウェアがファイルに書き込まれる/含まれる順序が、ダウンストリームで実行される順序であるということです。ミドルウェアでyieldステートメントをヒットするとすぐに、最後に到達するまで、次のミドルウェアに切り替わります。次に、再び上に移動して、yieldステートメントから関数を再開します。

たとえば、次のコードスニペットでは、最初の関数が最初にyieldまで実行され、次に2番目のミドルウェアがyieldまで実行され、次に3番目が実行されます。ここにはミドルウェアがもうないので、逆の順序、つまり3番目、2番目、1番目の順序で実行して戻り始めます。この例は、ミドルウェアをKoaの方法で使用する方法をまとめたものです。

var koa = require('koa');
var app = koa();

//Order of middlewares
app.use(first);
app.use(second);
app.use(third);

function *first(next) {
   console.log("I'll be logged first. ");
   
   //Now we yield to the next middleware
   yield next;
   
   //We'll come back here at the end after all other middlewares have ended
   console.log("I'll be logged last. ");
};

function *second(next) {
   console.log("I'll be logged second. ");
   yield next;
   console.log("I'll be logged fifth. ");
};

function *third(next) {
   console.log("I'll be logged third. ");
   yield next;
   console.log("I'll be logged fourth. ");
};

app.listen(3000);

このコードを実行した後に「/」にアクセスすると、コンソールで次のようになります。

I'll be logged first. 
I'll be logged second. 
I'll be logged third. 
I'll be logged fourth. 
I'll be logged fifth. 
I'll be logged last.

次の図は、上記の例で実際に起こっていることをまとめたものです。

独自のミドルウェアを作成する方法がわかったので、コミュニティで作成された最も一般的に使用されるミドルウェアについて説明します。

サードパーティのミドルウェア

Express用のサードパーティミドルウェアのリストは、こちらから入手できます。以下は、最も一般的に使用されるミドルウェアの一部です-

  • koa-bodyparser
  • koa-router
  • koa-static
  • koa-compress

以降の章では、複数のミドルウェアについて説明します。

パグはテンプレートエンジンです。テンプレートエンジンは、HTMLを使用したサーバーコードの乱雑さを取り除き、文字列を既存のHTMLテンプレートに乱暴に連結するために使用されます。Pugは非常に強力なテンプレートエンジンであり、次のようなさまざまな機能を備えています。filters, includes, inheritance, interpolation、など。これをカバーするための多くの根拠があります。

KoaでPugを使用するには、次のコマンドを使用してPugをインストールする必要があります。

$ npm install --save pug koa-pug

パグをインストールしたら、アプリのテンプレートエンジンとして設定します。次のコードをapp.jsファイルに追加します。

var koa = require('koa');
var router = require('koa-router');
var app = koa();

var Pug = require('koa-pug');
var pug = new Pug({
   viewPath: './views',
   basedir: './views',
   app: app //Equivalent to app.use(pug)
});

var _ = router(); //Instantiate the router

app.use(_.routes()); //Use the routes defined using the router
app.listen(3000);

次に、viewsという新しいディレクトリを作成します。ディレクトリ内にfirst_view.pugという名前のファイルを作成し、その中に次のデータを入力します。

doctype html
html
   head
      title = "Hello Pug"
   body
      p.greetings#people Hello Views!

このページを実行するには、次のルートをアプリに追加します。

_.get('/hello', getMessage); // Define routes

function *getMessage(){
   this.render('first_view');
};

次のように出力を受け取ります-

Pugが行うことは、この非常に単純な外観のマークアップをhtmlに変換することです。タグの終了を追跡する必要はありません。classキーワードとidキーワードを使用する必要はなく、「。」を使用します。および「#」でそれらを定義します。上記のコードは最初にに変換されます

<!DOCTYPE html>
<html>
   <head>
      <title>Hello Pug</title>
   </head>
    
   <body>
      <p class = "greetings" id = "people">Hello Views!</p>
   </body>
</html>

Pugは、HTMLマークアップを単純化する以上のことを実行できます。Pugのこれらの機能のいくつかを調べてみましょう。

シンプルなタグ

タグは、インデントに従ってネストされます。上記の例のように、<title> 内でインデントされました <head>タグなので、中にありました。しかし<body> タグは同じインデントにあったので、の兄弟でした <head> 鬼ごっこ。

タグを閉じる必要はありません。Pugが同じまたは外側のインデントレベルで次のタグに遭遇するとすぐに、タグを閉じます。

タグ内にテキストを配置する方法は3つあります-

  • 分離されたスペース-
h1 Welcome to Pug
  • パイプテキスト-
div
   | To insert multiline text, 
   | You can use the pipe operator.
  • テキストのブロック-
div.
   But that gets tedious if you have a lot of text. 
   You can use "." at the end of tag to denote block of text. 
   To put tags inside this block, simply enter tag in a new line and 
   indent it accordingly.

コメント

Pugは、コメントの作成にJavaScript(//)と同じ構文を使用します。これらのコメントはhtmlコメント(<!-comment->)に変換されます。例えば、

//This is a Pug comment

このコメントは-に変換されます

<!--This is a Pug comment-->

属性

属性を定義するには、括弧内にコンマで区切られた属性のリストを使用します。クラス属性とID属性には特別な表現があります。次のコード行では、特定のhtmlタグの属性、クラス、およびIDの定義について説明します。

div.container.column.main#division(width = "100",height = "100")

このコード行は、-に変換されます

<div class = "container column main" id = "division" width = "100" height = "100"></div>

テンプレートへの値の受け渡し

Pugテンプレートをレンダリングするとき、実際にはルートハンドラーから値を渡すことができ、それをテンプレートで使用できます。次のコードを使用して、新しいルートハンドラーを作成します。

var koa = require('koa');
var router = require('koa-router');
var app = koa();

var Pug = require('koa-pug');
var pug = new Pug({
   viewPath: './views',
   basedir: './views',
   app: app // equals to pug.use(app) and app.use(pug.middleware)
});

var _ = router(); //Instantiate the router

_.get('//dynamic_view', dynamicMessage); // Define routes

function *dynamicMessage(){
   this.render('dynamic', {
      name: "TutorialsPoint", 
      url:"https://www.tutorialspoint.com"
   });
};

app.use(_.routes()); //Use the routes defined using the router
app.listen(3000);

次に、次のコードを使用して、viewsディレクトリにdynamic.pugという名前の新しいビューファイルを作成します。

html
   head
      title = name
   body
      h1 = name
      a(href = url) URL

開いた localhost:3000/dynamicお使いのブラウザで以下が出力されるはずです。−

これらの渡された変数をテキスト内で使用することもできます。タグのテキストの間に渡された変数を挿入するには、#{variableName}構文を使用します。たとえば、上記の例で、TutorialsPointからGreetingsを挿入する場合は、次のコードを使用する必要があります。

html
   head
      title = name
   body
      h1 Greetings from #{name}
      a(href = url) URL

値を使用するこの方法は、補間と呼ばれます。

条件付き

条件文とループ構造も使用できます。この実際的な例を考えてみましょう。ユーザーがログインしている場合は「こんにちは、ユーザー」を表示し、そうでない場合は「ログイン/サインアップ」リンクを表示します。これを実現するために、次のような単純なテンプレートを定義できます。

html
   head
      title Simple template
   body
      if(user)
         h1 Hi, #{user.name}
      else
         a(href = "/sign_up") Sign Up

ルートを使用してこれをレンダリングするとき、および-のようなオブジェクトを渡す場合

this.render('/dynamic',{user: 
   {name: "Ayush", age: "20"}
});

こんにちは、アユッシュを表示するメッセージが表示されます。ただし、オブジェクトを渡さない場合、またはユーザーキーなしで渡す場合は、[サインアップ]リンクが表示されます。

インクルードとコンポーネント

Pugは、Webページのコンポーネントを作成するための非常に直感的な方法を提供します。たとえば、ニュースWebサイトを表示した場合、ロゴとカテゴリを含むヘッダーは常に固定されています。それをすべてのビューにコピーする代わりに、インクルードを使用できます。次の例は、include-を使用する方法を示しています。

次のコードで3つのビューを作成します-

header.pug

div.header.
   I'm the header for this website.

content.pug

html
   head
      title Simple template
   body
      include ./header.pug
      h3 I'm the main content
      include ./footer.pug

footer.pug

div.footer.
   I'm the footer for this website.

このためのルートを次のように作成します。

var koa = require('koa');
var router = require('koa-router');
var app = koa();

var Pug = require('koa-pug');
var pug = new Pug({
   viewPath: './views',
   basedir: './views',
   app: app //Equivalent to app.use(pug)
});

var _ = router(); //Instantiate the router

_.get('/components', getComponents);

function *getComponents(){
   this.render('content.pug');
}

app.use(_.routes()); //Use the routes defined using the router
app.listen(3000);

に移動 localhost:3000/components、次の出力が得られるはずです。

include プレーンテキスト、CSS、JavaScriptを含めるためにも使用できます。

パグには他にもたくさんの機能があります。ただし、これらはこのチュートリアルの範囲外です。PugでPugをさらに探索できます。

フォームはウェブの不可欠な部分です。私たちが訪問するほとんどすべてのウェブサイトは、私たちのためにいくつかの情報を送信または取得するフォームを提供しています。フォームの使用を開始するには、最初にkoa-bodyをインストールします。これをインストールするには、ターミナルに移動して-を使用します

$ npm install --save koa-body

app.jsファイルの内容を次のコードに置き換えます。

var koa = require('koa');
var router = require('koa-router');
var bodyParser = require('koa-body');
var app = koa();

//Set up Pug
var Pug = require('koa-pug');
var pug = new Pug({
   viewPath: './views',
   basedir: './views',
   app: app //Equivalent to app.use(pug)
});

//Set up body parsing middleware
app.use(bodyParser({
   formidable:{uploadDir: './uploads'},
   multipart: true,
   urlencoded: true
}));

_.get('/', renderForm);
_.post('/', handleForm);

function * renderForm(){
   this.render('form');
}
function *handleForm(){
   console.log(this.request.body);
   console.log(this.req.body);
   this.body = this.request.body; //This is where the parsed request is stored
}

app.use(_.routes()); 
app.listen(3000);

ここで行っている新しいことは、ボディパーサーとマルターをインポートすることです。jsonおよびx-www-form-urlencodedヘッダーリクエストの解析にはbodyパーサーを使用し、multipart / form-dataの解析にはmulterを使用しています。

これをテストするためのhtmlフォームを作成しましょう!次のコードを使用して、form.pugという名前の新しいビューを作成します。

html
   head
      title Form Tester
   body
      form(action = "/", method = "POST")
         div
            label(for = "say") Say: 
            input(name = "say" value = "Hi")
         br
         div
            label(for = "to") To: 
            input(name = "to" value = "Koa form")
         br
         button(type = "submit") Send my greetings

−を使用してサーバーを実行します

nodemon index.js

次に、localhost:3000 /に移動し、必要に応じてフォームに入力して送信します。次のように応答を受け取ります-

コンソールを見てください。JavaScriptオブジェクトとしてリクエストの本文が表示されます。例-

ザ・ this.request.bodyオブジェクトには、解析されたリクエスト本文が含まれます。そのオブジェクトのフィールドを使用するには、通常のJSオブジェクトとして使用します。

これは、リクエストを送信する1つの方法にすぎません。他にも多くの方法がありますが、Koaアプリはこれらすべてのリクエストを同じ方法で処理するため、ここで説明することは関係ありません。リクエストを行うさまざまな方法の詳細については、このページをご覧ください。

Webアプリケーションは、ファイルのアップロードを許可する機能を提供する必要があります。クライアントからファイルを受信して​​サーバーに保存する方法を見てみましょう。

リクエストの解析には、koa-bodyミドルウェアをすでに使用しています。このミドルウェアは、ファイルのアップロードの処理にも使用されます。ファイルをアップロードしてから、Koaを使用してこれらのファイルを保存できるフォームを作成しましょう。まず、という名前のテンプレートを作成しますfile_upload.pug 以下の内容で。

html
   head
      title File uploads
   body
      form(action = "/upload" method = "POST" enctype = "multipart/form-data")
         div
            input(type = "text" name = "name" placeholder = "Name")
         
         div
            input(type = "file" name = "image")
         
         div
            input(type = "submit")

フォームに上記と同じエンコーディングタイプを指定する必要があることに注意してください。次に、このデータをサーバーで処理しましょう。

var koa = require('koa');
var router = require('koa-router');
var bodyParser = require('koa-body');
var app = koa();

//Set up Pug
var Pug = require('koa-pug');
var pug = new Pug({
   viewPath: './views',
   basedir: './views',
   app: app 
});

//Set up body parsing middleware
app.use(bodyParser({
   formidable:{uploadDir: './uploads'},    //This is where the files would come
   multipart: true,
   urlencoded: true
}));

var _ = router(); //Instantiate the router

_.get('/files', renderForm);
_.post('/upload', handleForm);

function * renderForm(){
   this.render('file_upload');
}

function *handleForm(){
   console.log("Files: ", this.request.body.files);
   console.log("Fields: ", this.request.body.fields);
   this.body = "Received your data!"; //This is where the parsed request is stored
}

app.use(_.routes()); 
app.listen(3000);

これを実行すると、次のフォームが表示されます。

これを送信すると、コンソールは次の出力を生成します。

アップロードされたファイルは、上記の出力のパスに保存されます。を使用してリクエスト内のファイルにアクセスできますthis.request.body.files とそのリクエストのフィールド this.request.body.fields

静的ファイルは、クライアントがサーバーからそのままダウンロードするファイルです。新しいディレクトリを作成し、public。Expressでは、デフォルトでは静的ファイルを提供できません。

この目的を果たすにはミドルウェアが必要です。先に進んでインストールkoa-serve

$ npm install --save koa-static

今、私たちはする必要があります useこのミドルウェア。その前に、publicというディレクトリを作成します。すべての静的ファイルをここに保存します。これにより、このパブリックフォルダーの上にはクライアントがアクセスできないため、サーバーコードを安全に保つことができます。パブリックディレクトリを作成したら、という名前のファイルを作成しますhello.txtあなたが好きなコンテンツでそれに。次に、以下をapp.jsに追加します。

var serve = require('koa-static');
var koa = require('koa');
var app = koa();

app.use(serve('./public'));

app.listen(3000);

Note− Koaは静的ディレクトリに関連するファイルを検索するため、静的ディレクトリの名前はURLの一部ではありません。これでルートルートがパブリックディレクトリに設定されたため、ロードするすべての静的ファイルはパブリックをルートと見なします。これが正常に機能していることをテストするには、アプリを実行してhttps://localhost:3000/hello.txt

次の出力が得られるはずです。これはHTMLドキュメントやPugビューではなく、単純なtxtファイルであることに注意してください。

複数の静的dir

−を使用して複数の静的アセットディレクトリを設定することもできます

var serve = require('koa-static');
var koa = require('koa');
var app = koa();

app.use(serve('./public'));
app.use(serve('./images'));

app.listen(3000);

これで、ファイルを要求すると、Koaはこれらのディレクトリを検索し、一致するファイルを送信します。

Cookieは、サーバーリクエストでクライアントに送信され、クライアント側に保存される単純な小さなファイル/データです。ユーザーがウェブサイトを再度読み込むたびに、このCookieはリクエストとともに送信されます。これは、ユーザーのアクションを追跡するのに役立ちます。HTTPCookieにはさまざまな用途があります。

  • セッション管理
  • パーソナライズ(レコメンデーションシステム)
  • ユーザー追跡

KoaでCookieを使用するには、次の機能があります。 ctx.cookies.set() そして ctx.cookies.get()。新しいCookieを設定するには、Koaアプリで新しいルートを定義しましょう。

var koa = require('koa');
var router = require('koa-router');
var app = koa();

_.get('/', setACookie);

function *setACookie() {
   this.cookies.set('foo', 'bar', {httpOnly: false});
}

var _ = router();

app.use(_.routes());
app.listen(3000);

Cookieが設定されているかどうかを確認するには、ブラウザに移動してコンソールを起動し、「-」と入力します。

console.log(document.cookie);

これにより、次の出力が生成されます(ブラウザの拡張機能が原因で、Cookieがさらに設定されている可能性があります)。

"foo = bar"

上記の例を次に示します。

また、ブラウザはサーバーにクエリを実行するたびにCookieを送り返します。サーバー上のCookieを表示するには、ルート内のサーバーコンソールで、次のコードをそのルートに追加します。

console.log('Cookies: foo = ', this.cookies.get('foo'));

次回このルートにリクエストを送信すると、次の出力が得られます。

Cookies: foo = bar

有効期限付きのCookieの追加

有効期限が切れるCookieを追加できます。有効期限が切れるCookieを追加するには、プロパティ「expires」が期限切れになる時間に設定されたオブジェクトを渡すだけです。例えば、

var koa = require('koa');
var router = require('koa-router');
var app = koa();

_.get('/', setACookie);

function *setACookie(){
   //Expires after 360000 ms from the time it is set.
	this.cookies.set('name', 'value', { 
      httpOnly: false, expires: 360000 + Date.now() });
}

var _ = router();

app.use(_.routes());
app.listen(3000);

既存のCookieの削除

Cookieの設定を解除するには、Cookieを空の文字列に設定するだけです。たとえば、という名前のCookieをクリアする必要がある場合foo、次のコードを使用します。

var koa = require('koa');
var router = require('koa-router');
var app = koa();

_.get('/', setACookie);

function *setACookie(){
   //Expires after 360000 ms from the time it is set.
   this.cookies.set('name', '');
}

var _ = router();

app.use(_.routes());
app.listen(3000);

これにより、上記のCookieの設定が解除されます。あなたは去るべきであることに注意してくださいHttpOnly クライアント側のコードでCookieを使用しない場合にtrueになるオプション。

HTTPはステートレスであるため、リクエストを他のリクエストに関連付けるには、HTTPリクエスト間でユーザーデータを保存する方法が必要です。CookieとURLパラメータはどちらも、クライアントとサーバー間でデータを転送するための適切な方法です。ただし、どちらもクライアント側で読み取ることができます。セッションはまさにこの問題を解決します。クライアントにIDを割り当てると、そのIDを使用してそれ以降のすべての要求が行われます。クライアントに関連付けられた情報は、このIDにリンクされたサーバーに保存されます。

koa-sessionが必要なので、−を使用してインストールします。

npm install --save koa-session

入れます koa-sessionミドルウェアが設置されています。この例では、RAMを使用してセッションを保存します。これを実稼働環境で使用しないでください。セッションミドルウェアは、セッションの作成、セッションCookieの設定、コンテキストオブジェクトでのセッションオブジェクトの作成など、すべてを処理します。

同じクライアントから再度リクエストを行うと、セッション情報が保存されます(サーバーが再起動されていない場合)。このセッションオブジェクトにさらにプロパティを追加できます。次の例では、クライアントのビューカウンターを作成します。

var session = require('koa-session');
var koa = require('koa');
var app = koa();

app.keys = ['Shh, its a secret!'];
app.use(session(app));  // Include the session middleware

app.use(function *(){
   var n = this.session.views || 0;
   this.session.views = ++n;
   
   if(n === 1)
      this.body = 'Welcome here for the first time!';
   else
      this.body = "You've visited this page " + n + " times!";
})

app.listen(3000);

上記のコードは、ユーザーがサイトにアクセスすると、ユーザーの新しいセッションを作成し、Cookieを割り当てます。次回ユーザーがアクセスすると、Cookieがチェックされ、それに応じてpage_viewセッション変数が更新されます。

アプリを実行して localhost:3000, 次の応答が返されます。

ページに再度アクセスすると、ページカウンターが増加します。この場合、ページは12回更新されました。

認証は、提供された資格情報が、ローカルオペレーティングシステムまたは認証サーバー内の許可されたユーザーの情報のデータベースにファイルされている資格情報と比較されるプロセスです。資格情報が一致する場合、プロセスは完了し、ユーザーにはアクセスの許可が付与されます。

を使用する非常に基本的な認証システムを作成します Basic HTTP Authentication。これは、Cookieやセッションなどを必要としないため、アクセス制御を実施するための最も簡単な方法です。これを使用するには、クライアントは、要求するたびにAuthorizationヘッダーを送信する必要があります。ユーザー名とパスワードは暗号化されていませんが、次のように1つの文字列に連結されています。

username:password

この文字列はBase64でエンコードされており、この値の前にBasicという単語が付けられています。たとえば、ユーザー名がAyushで、パスワードがIndiaの場合、文字列は"Ayush:India" 承認ヘッダーにエンコードされた状態で送信されます。

Authorization: Basic QXl1c2g6SW5kaWE=

これをkoaアプリに実装するには、koa-basic-authミドルウェアが必要です。−を使用してインストールします

$ npm install --save koa-basic-auth

次に、app.jsファイルを開き、次のコードを入力します。

//This is what the authentication would be checked against
var credentials = { name: 'Ayush', pass: 'India' }

var koa = require('koa');
var auth = require('koa-basic-auth');
var _ = require('koa-router')();

var app = koa();

//Error handling middleware
app.use(function *(next){
   try {
      yield next;
   } catch (err) {
      if (401 == err.status) {
         this.status = 401;
         this.set('WWW-Authenticate', 'Basic');
         this.body = 'You have no access here';
      } else {
         throw err;
      }
   }
});

// Set up authentication here as first middleware. 
// This returns an error if user is not authenticated.
_.get('/protected', auth(credentials), function *(){
   this.body = 'You have access to the protected area.';
   yield next;
});

// No authentication middleware present here.
_.get('/unprotected', function*(next){
   this.body = "Anyone can access this area";
   yield next;
});

app.use(_.routes());
app.listen(3000);

すべての認証関連エラーを処理するためのエラー処理ミドルウェアを作成しました。次に、2つのルートを作成しました-

  • /protected−このルートにアクセスできるのは、ユーザーが正しい認証ヘッダーを送信した場合のみです。他のすべての場合、エラーが発生します。

  • /unprotected −このルートには、認証の有無にかかわらず、誰でもアクセスできます。

これで、認証ヘッダーなしで、または間違った資格情報を使用して/ protectedにリクエストを送信すると、エラーが発生します。例えば、

$ curl https://localhost:3000/protected

次のように応答を受け取ります-

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic
Content-Type: text/plain; charset=utf-8
Content-Length: 28
Date: Sat, 17 Sep 2016 19:05:56 GMT
Connection: keep-alive

Please authenticate yourself

ただし、適切な資格情報を使用すると、期待どおりの応答が得られます。例えば、

$ curl -H "Authorization: basic QXl1c2g6SW5kaWE=" https://localhost:3000/protected -i

次のように応答が返されます-

HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Content-Length: 38
Date: Sat, 17 Sep 2016 19:07:33 GMT
Connection: keep-alive

You have access to the protected area.

/ unprotectedルートは、引き続き誰でもアクセスできます。

圧縮は、帯域幅を節約し、サイトを高速化するためのシンプルで効果的な方法です。最新のブラウザとのみ互換性があり、ユーザーがレガシーブラウザも使用している場合は注意して使用する必要があります。

サーバーから応答を送信するときに圧縮を使用すると、ロード時間を大幅に改善できます。と呼ばれるミドルウェアを使用しますkoa-compress ファイルの圧縮と適切なヘッダーの設定を処理します。

先に進み、-を使用してミドルウェアをインストールします

$ npm install --save koa-compress

app.jsファイルに、次のコードを追加します-

var koa = require('koa');
var router = require('koa-router');
var app = koa();

var Pug = require('koa-pug');
var pug = new Pug({
   viewPath: './views',
   basedir: './views',
   app: app //Equivalent to app.use(pug)
});

app.use(compress({
   filter: function (content_type) {
      return /text/i.test(content_type)
   },
   threshold: 2048,
   flush: require('zlib').Z_SYNC_FLUSH
}));

var _ = router(); //Instantiate the router

_.get('/', getRoot);

function *getRoot(next){
   this.render('index');
}

app.use(_.routes()); //Use the routes defined using the router
app.listen(3000);

これにより、圧縮ミドルウェアが配置されます。フィルタオプションは、応答コンテンツタイプをチェックして、圧縮するかどうかを決定する関数です。しきい値オプションは、圧縮する最小応答サイズ(バイト単位)です。これにより、小さな応答をすべて圧縮する必要がなくなります。

以下は、圧縮なしの応答です。

以下は、圧縮による同様の応答です。

下部の[サイズ]タブを見ると、2つの違いがよくわかります。ファイルを圧縮すると、150%以上の改善が見られます。

キャッシングは、後続のリクエストを高速化するために再利用可能な応答を保存するための用語です。すべてのブラウザには、HTTPキャッシュの実装が付属しています。私たちがしなければならないのは、各サーバーの応答が正しいHTTPヘッダーディレクティブを提供して、ブラウザーが応答をキャッシュできるタイミングと期間をブラウザーに指示することです。

以下は、Webアプリにキャッシュを含めることのいくつかの利点です-

  • ネットワークコストが削減されます。コンテンツがキャッシュされている場合は、後続のリクエストごとに送信する必要のあるコンテンツの量が少なくなります。

  • ウェブサイトの速度とパフォーマンスが向上します。

  • クライアントがオフラインの場合でも、コンテンツを利用できるようにすることができます。

koa-static-cacheミドルウェアを使用して、アプリにキャッシュを実装します。−を使用してこれらのミドルウェアをインストールします

$ npm install --save koa-static-cache

app.jsファイルに移動し、次のコードを追加します。

var koa = require('koa');
var app = koa();

var path = require('path');
var staticCache = require('koa-static-cache');

app.use(staticCache(path.join(__dirname, 'public'), {
   maxAge: 365 * 24 * 60 * 60  //Add these files to caches for a year
}))

app.listen(3000);

ザ・ koa-static-cacheミドルウェアは、クライアント側でサーバーの応答をキャッシュするために使用されます。ザ・cache-controlヘッダーは、キャッシュオブジェクトの初期化時に提供するオプションに従って設定されます。このキャッシュされた応答の有効期限を1年に設定しました。以下は、ファイルがキャッシュされる前後に送信されたリクエストの比較です。

このファイルがキャッシュされる前は、返されたステータスコードは200でしたが、これは問題ありません。応答ヘッダーには、キャッシュされるコンテンツに関する複数の情報が含まれており、ETag コンテンツのために。

次回リクエストが送信されたときは、ETtagと一緒に送信されました。サーバー上でコンテンツが変更されていないため、対応するETagも同じままであり、クライアントは、ローカルにあるコピーがサーバーが提供するものと最新であり、要求する代わりにローカルのものを使用する必要があることを通知されました。再び。

Note−キャッシュされたファイルを無効にするには、ファイル名を変更して参照を更新するだけです。これにより、クライアントに送信する新しいファイルが確保され、クライアントはそのファイルをキャッシュから読み戻すことができなくなります。

リクエストを受け取っていますが、どこにも保存していません。データを保存するためのデータベースが必要です。と呼ばれる有名なNoSQLデータベースを使用しますMongoDB。Mongoをインストールして読むには、このリンクにアクセスしてください。

KoaでMongoを使用するには、ノードのクライアントAPIが必要です。私たちには複数のオプションがありますが、このチュートリアルではマングースに固執します。マングースはdocument modelingMongoDBのノードで。ドキュメントモデリングとは、Model (のように class ドキュメント指向プログラミングで)、そして私たちは生産します documents このモデルを使用して(私たちが作成するように) documents of a classOOPで)。すべての処理はこれらの「ドキュメント」に対して実行され、最後にこれらのドキュメントをデータベースに書き込みます。

マングースの設定

Mongoがインストールされたので、他のノードパッケージをインストールするのと同じ方法でmongooseをインストールしましょう。

$ npm install --save mongoose

mongooseの使用を開始する前に、Mongoシェルを使用してデータベースを作成する必要があります。新しいデータベースを作成するには、ターミナルを開いて「mongo」と入力します。Mongoシェルが起動します。次のように入力します。

use my_db

新しいデータベースが作成されます。Mongoシェルを開くと、デフォルトで「test」dbになり、上記と同じコマンドを使用してデータベースに変更する必要があります。

mongooseを使用するには、app.jsファイルでそれを要求してから、mongodb:// localhostで実行されているmongodサービスに接続します。

var koa = require('koa');
var _ = require('koa-router')();
var app = koa();

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/my_db');

app.use(_.routes());
app.listen(3000);

これでアプリがデータベースに接続されました。新しいモデルを作成しましょう。このモデルは、データベースのコレクションとして機能します。新しいモデルを作成するには、ルートを定義する前に、次のコードを使用します。

var koa = require('koa');
var _ = require('koa-router')();
var app = koa();

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/my_db');

var personSchema = mongoose.Schema({
   name: String,
   age: Number,
   nationality: String
});

var Person = mongoose.model("Person", personSchema);

app.use(_.routes());
app.listen(3000);

上記のコードは、人のスキーマを定義し、マングースモデルを作成するために使用されます Person

ドキュメントの保存

次に、新しいhtmlフォームを作成します。このフォームは、個人の詳細を取得してデータベースに保存します。フォームを作成するには、viewsディレクトリにperson.pugという新しいビューファイルを次の内容で作成します。

html
   head
      title Person
   body
      form(action = "/person", method = "POST")
         div
            label(for = "name") Name: 
            input(name = "name")
         br
         div
            label(for = "age") Age: 
            input(name = "age")
         br
         div
            label(for = "nationality") Nationality: 
            input(name = "nationality")
         br
         button(type = "submit") Create new person

また、index.jsに新しいget routeを追加して、このドキュメントをレンダリングします。

var koa = require('koa');
var _ = require('koa-router')();
var app = koa();

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/my_db');

var personSchema = mongoose.Schema({
   name: String,
   age: Number,
   nationality: String
});

var Person = mongoose.model("Person", personSchema);

_.get('/person', getPerson);

function *getPerson(next){
   this.render('person');
   yield next;
}

app.use(_.routes());
app.listen(3000);

localhost:3000 / personに移動して、フォームが正しく表示されているかどうかを確認します。これは単なるUIであり、まだ機能していないことに注意してください。これが私たちのフォームの外観です。

次に、このリクエストを処理するポストルートハンドラーを「/ person」に定義します。

var koa = require('koa');
var _ = require('koa-router')();
var app = koa();

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/my_db');

var personSchema = mongoose.Schema({
   name: String,
   age: Number,
   nationality: String
});

var Person = mongoose.model("Person", personSchema);

_.post('/person', createPerson);

function *createPerson(next){
   var self = this;
   var personInfo = self.request.body; //Get the parsed information
   
   if(!personInfo.name || !personInfo.age || !personInfo.nationality){
      self.render(
         'show_message', {message: "Sorry, you provided wrong info", type: "error"});
   } else {
      var newPerson = new Person({
         name: personInfo.name,
         age: personInfo.age,
         nationality: personInfo.nationality
      });
      yield newPerson.save(function(err, res) {
         if(err)
            self.render('show_message', 
               {message: "Database error", type: "error"});
         else
            self.render('show_message', 
               {message: "New person added", type: "success", person: personInfo});
      });
   }
}

app.use(_.routes());
app.listen(3000);

上記のコードでは、空のフィールドを受け取った場合、またはフィールドを受け取らなかった場合、エラー応答を送信します。ただし、整形式のドキュメントを受け取った場合は、PersonモデルからnewPersonドキュメントを作成し、を使用してDBに保存します。newPerson.save()関数。これはマングースで定義され、引数としてコールバックを受け入れます。このコールバックには2つの引数があります。error そして response。これによりshow_messageビューがレンダリングされるため、これも作成する必要があります。

このルートからの応答を表示するには、 show_message見る。次のコードで新しいビューを作成します。

html
   head
      title Person
   body
      if(type = "error")
         h3(style = "color:red") #{message}
      else
         h3 New person, name: 
            #{person.name}, age: 
            #{person.age} and nationality: 
            #{person.nationality} added!

以下は、フォーム(show_message.pug)を正常に送信したときに受け取る応答です。

これで、人を作成するためのインターフェイスができました。

ドキュメントの取得

Mongooseは、ドキュメントを取得するための多くの機能を提供します。そのうちの3つに焦点を当てます。これらの関数はすべて、最後のパラメーターとしてコールバックも受け取ります。save関数と同様に、引数はエラーと応答です。

3つの機能は次のとおりです。

Model.find(条件、コールバック)

この関数は、条件オブジェクトのフィールドに一致するすべてのドキュメントを検索します。Mongoで使用されているのと同じ演算子がmongooseでも機能します。たとえば、これにより、個人のコレクションからすべてのドキュメントがフェッチされます。

Person.find(function(err, response){
   console.log(response);
});

これにより、フィールド名が「Ayush」で年齢が20のすべてのドキュメントがフェッチされます。

Person.find({name: "Ayush", age: 20}, 
   function(err, response){
      console.log(response);
   });

また、必要な予測、つまり必要なフィールドを提供することもできます。たとえば、names その人々の nationality「インド」で、使用します-

Person.find({nationality: "Indian"}, 
   "name", function(err, response) {
      console.log(response);
   });

Model.findOne(条件、コールバック)

この関数は、常に単一の最も関連性の高いドキュメントをフェッチします。Model.find()とまったく同じ引数があります。

Model.findById(id、callback)

この関数は、 _id(mongoで定義)最初の引数、オプションの射影文字列、および応答を処理するためのコールバック。例えば、

Person.findById("507f1f77bcf86cd799439011", 
   function(err, response){
      console.log(response);
   });

すべての人の記録を表示するルートを作成しましょう。

var koa = require('koa');
var _ = require('koa-router')();
var app = koa();

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/my_db');

var personSchema = mongoose.Schema({
   name: String,
   age: Number,
   nationality: String
});

var Person = mongoose.model("Person", personSchema);

_.get('/people', getPeople);
function *getPeople(next){
   var self = this;
   
   yield Person.find(function(err, response){
      self.body = response;
   });
}
app.use(_.routes());
app.listen(3000);

ドキュメントの更新

Mongooseは、ドキュメントを更新するための3つの機能を提供します。

Model.update(条件、更新、コールバック)

この関数は条件を受け取り、入力としてオブジェクトを更新し、コレクション内の条件に一致するすべてのドキュメントに変更を適用します。たとえば、次のコードは、国籍が「アメリカ人」になるようにすべての個人文書を更新します。

Person.update({age: 25},
   {nationality: "American"}, 
   function(err, response){
      console.log(response);
   });

Model.findOneAndUpdate(条件、更新、コールバック)

それはまさに言われていることをします。クエリに基づいて1つのドキュメントを検索し、2番目の引数に従ってそれを更新します。また、最後の引数としてコールバックを取ります。例えば、

Person.findOneAndUpdate({name: "Ayush"}, 
   {age: 40}, 
   function(err, response){
      console.log(response);
   });

Model.findByIdAndUpdate(id、updates、callback)

この関数は、IDで識別される単一のドキュメントを更新します。例えば、

Person.findByIdAndUpdate("507f1f77bcf86cd799439011", 
   {name: "James"}, 
   function(err, response){
      console.log(response);
   });

人を更新するルートを作成しましょう。これは、パラメータとしてIDを持ち、ペイロードに詳細があるPUTルートになります。

var koa = require('koa');
var _ = require('koa-router')();
var app = koa();
var mongoose = require('mongoose');

mongoose.connect('mongodb://localhost/my_db');

var personSchema = mongoose.Schema({
   name: String,
   age: Number,
   nationality: String
});

var Person = mongoose.model("Person", personSchema);

_.put('/people/:id', updatePerson);

function *updatePerson() {
   var self = this;
   yield Person.findByIdAndUpdate(self.params.id, 
      {$set: {self.request.body}}, function(err, response){
      
      if(err) {
         self.body = {
            message: "Error in updating person with id " + self.params.id};
      } else {
         self.body = response;
      }
   });
}

app.use(_.routes());
app.listen(3000);

このルートをテストするには、ターミナルに次のように入力します(IDを作成したユーザーのIDに置き換えます)。

curl -X PUT --data "name = James&age = 20&nationality = American" https://localhost:3000/people/507f1f77bcf86cd799439011

これにより、ルートで提供されたIDに関連付けられたドキュメントが上記の詳細で更新されます。

ドキュメントの削除

カバーしました Create、 Readと Update、マングースを使用してドキュメントを削除する方法を見ていきます。ここには、更新とまったく同じように3つの関数があります。

Model.remove(condition、[callback])

この関数は、条件オブジェクトを入力として受け取り、条件に一致するすべてのドキュメントを削除します。たとえば、20歳のすべての人を削除する必要がある場合

Person.remove({age:20});

Model.findOneAndRemove(condition、[callback])

この関数は、 single、条件オブジェクトに応じた最も関連性の高いドキュメント。例えば、

Person.findOneAndRemove({name: "Ayush"});

Model.findByIdAndRemove(id、[コールバック])

この関数は、IDで識別される単一のドキュメントを削除します。例えば、

Person.findByIdAndRemove("507f1f77bcf86cd799439011");

それでは、データベースから人を削除するルートを作成しましょう。

var koa = require('koa');
var _ = require('koa-router')();
var app = koa();

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/my_db');

var personSchema = mongoose.Schema({
   name: String,
   age: Number,
   nationality: String
});

var Person = mongoose.model("Person", personSchema);

_.delete('/people/:id', deletePerson);
function *deletePerson(next){
   var self = this;
   yield Person.findByIdAndRemove(self.params.id, function(err, response){
      if(err) {
         self.body = {message: "Error in deleting record id " + self.params.id};
      } else {
         self.body = {message: "Person with id " + self.params.id + " removed."};
      }
   });
}

app.use(_.routes());
app.listen(3000);

これをテストするには、次のcurlコマンドを使用します-

curl -X DELETE https://localhost:3000/people/507f1f77bcf86cd799439011

これにより、指定されたIDを持つ人が削除され、次のメッセージが生成されます。−

{message: "Person with id 507f1f77bcf86cd799439011 removed."}

これで、MongoDB、mongoose、Koaを使用して簡単なCRUDアプリケーションを作成する方法をまとめました。マングースをさらに詳しく調べるには、APIドキュメントをお読みください。

モバイルアプリケーション、シングルページアプリケーションを作成し、AJAX呼び出しを使用してクライアントにデータを提供するには、APIが必要です。これらのAPIとエンドポイントを構造化して名前を付ける方法の一般的なアーキテクチャスタイルは、REST(Representational Transfer State)。HTTP 1.1は、RESTの原則を念頭に置いて設計されました。RESTはによって導入されましたRoy Fielding 2000年に彼の論文FieldingDissertationsで。

RESTful URIとメソッドは、リクエストを処理するために必要なほぼすべての情報を提供します。次の表は、さまざまな動詞の使用方法とURIの命名方法をまとめたものです。最後にmoviesAPIを作成する予定なので、その構造について説明します。

方法 URI 詳細 関数
取得する /映画 安全で、追跡可能 すべての映画とその詳細のリストを取得します
取得する / movies / 1234 安全で、追跡可能 映画ID1234の詳細を取得します
役職 /映画 該当なし 詳細が提供された新しいムービーを作成します。応答には、この新しく作成されたリソースのURIが含まれています。
プット / movies / 1234 べき等 ムービーID1234を変更します(まだ存在しない場合は作成します)。応答には、この新しく作成されたリソースのURIが含まれています。
削除 / movies / 1234 べき等 ムービーID1234が存在する場合は、削除する必要があります。応答には、要求のステータスが含まれている必要があります。
削除または配置 /映画 無効 無効にする必要があります。DELETEとPUTは、作業しているリソースを指定する必要があります。

それでは、KoaでこのAPIを作成しましょう。JavaScriptでの操作が簡単で、他にも多くの利点があるため、トランスポートデータ形式としてJSONを使用します。index.jsファイルを次のように置き換えます-

INDEX.JS

var koa = require('koa');
var router = require('koa-router');
var bodyParser = require('koa-body');

var app = koa();

//Set up body parsing middleware
app.use(bodyParser({
   formidable:{uploadDir: './uploads'},
   multipart: true,
   urlencoded: true
}));

//Require the Router we defined in movies.js
var movies = require('./movies.js');

//Use the Router on the sub route /movies
app.use(movies.routes());

app.listen(3000);

アプリケーションのセットアップが完了したので、APIの作成に集中しましょう。まず、movies.jsファイルを設定します。私たちは映画を保存するためにデータベースを使用していませんが、それらをメモリに保存しているので、サーバーが再起動するたびに、私たちが追加した映画は消えます。これは、データベースまたはファイルを使用して(ノードfsモジュールを使用して)簡単に模倣できます。

koa-routerをインポートし、ルーターを作成して、module.exportsを使用してエクスポートします。

var Router = require('koa-router');
var router = Router({
  prefix: '/movies'
});  //Prefixed all routes with /movies

var movies = [
   {id: 101, name: "Fight Club", year: 1999, rating: 8.1},
   {id: 102, name: "Inception", year: 2010, rating: 8.7},
   {id: 103, name: "The Dark Knight", year: 2008, rating: 9},
   {id: 104, name: "12 Angry Men", year: 1957, rating: 8.9}
];

//Routes will go here

module.exports = router;

ルートを取得

すべての映画を取得するためのGETルートを定義します。

router.get('/', sendMovies);
function *sendMovies(next){
   this.body = movies;
   yield next;
}

それでおしまい。これが正常に機能しているかどうかをテストするには、アプリを実行し、ターミナルを開いて「-」と入力します。

curl -i -H "Accept: application/json" -H "Content-Type: application/json" -X GET localhost:3000/movies

次の応答が返されます-

[{"id":101,"name":"Fight 
Club","year":1999,"rating":8.1},{"id":102,"name":"Inception","year":2010,"rating":8.7},
{"id":103,"name":"The Dark Knight","year":2008,"rating":9},{"id":104,"name":"12 Angry 
Men","year":1957,"rating":8.9}]

すべての映画を入手するルートがあります。それでは、IDで特定の映画を取得するためのルートを作成しましょう。

router.get('/:id([0-9]{3,})', sendMovieWithId);

function *sendMovieWithId(next){
   var ctx = this;
   var currMovie = movies.filter(function(movie){
      if(movie.id == ctx.params.id){
         return true;
      }
   });
   if(currMovie.length == 1){
      this.body = currMovie[0];
   } else {
      this.response.status = 404;//Set status to 404 as movie was not found
      this.body = {message: "Not Found"};
   }
   yield next;
}

これにより、提供したIDに従って映画が取得されます。これをテストするには、ターミナルで次のコマンドを使用します。

curl -i -H "Accept: application/json" -H "Content-Type: application/json" -X GET localhost:3000/movies/101

次のように応答が返されます-

{"id":101,"name":"Fight Club","year":1999,"rating":8.1}

無効なルートにアクセスすると、GET不可エラーが発生しますが、IDが存在しない有効なルートにアクセスすると、404エラーが発生します。

GETルートはこれで完了です。それでは、POSTルートに移りましょう。

POSTルート

次のルートを使用して、POSTされたデータを処理します。

router.post('/', addNewMovie);

function *addNewMovie(next){
   //Check if all fields are provided and are valid:
   if(!this.request.body.name || 
      !this.request.body.year.toString().match(/^[0-9]{4}$/g) || 
      !this.request.body.rating.toString().match(/^[0-9]\.[0-9]$/g)){
      
      this.response.status = 400;
      this.body = {message: "Bad Request"};
   } else {
      var newId = movies[movies.length-1].id+1;
      
      movies.push({
         id: newId,
         name: this.request.body.name,
         year: this.request.body.year,
         rating: this.request.body.rating
      });
      this.body = {message: "New movie created.", location: "/movies/" + newId};
   }
   yield next;
}

これにより、新しいムービーが作成され、movies変数に保存されます。このルートをテストするには、ターミナルに次のように入力します-

curl -X POST --data "name = Toy%20story&year = 1995&rating = 8.5" 
https://localhost:3000/movies

次の応答が返されます-

{"message":"New movie created.","location":"/movies/105"}

これがmoviesオブジェクトに追加されたかどうかをテストするには、/ movies / 105のgetリクエストを再度実行します。次の応答が返されます-

{"id":105,"name":"Toy story","year":"1995","rating":"8.5"}

次に、PUTルートとDELETEルートを作成しましょう。

PUTルート

PUTルートはPOSTルートとほぼ同じです。更新/作成されるオブジェクトのIDを指定します。次の方法でルートを作成します-

router.put('/:id', updateMovieWithId);

function *updateMovieWithId(next){
   //Check if all fields are provided and are valid:
   if(!this.request.body.name || 
      !this.request.body.year.toString().match(/^[0-9]{4}$/g) || 
      !this.request.body.rating.toString().match(/^[0-9]\.[0-9]$/g) ||
      !this.params.id.toString().match(/^[0-9]{3,}$/g)){
      
      this.response.status = 400;
      this.body = {message: "Bad Request"};
   } else {
      //Gets us the index of movie with given id.
      var updateIndex = movies.map(function(movie){
         return movie.id;
      }).indexOf(parseInt(this.params.id));
      
      if(updateIndex === -1){
         //Movie not found, create new movies.push({
            id: this.params.id,
            name: this.request.body.name,
            year: this.request.body.year,
            rating: this.request.body.rating
         });
         this.body = {message: "New movie created.", location: "/movies/" + this.params.id};    
      } else {
         //Update existing movie
         movies[updateIndex] = {
            id: this.params.id,
            name: this.request.body.name,
            year: this.request.body.year,
            rating: this.request.body.rating
         };
         this.body = {message: "Movie id " + this.params.id + " updated.", location: "/movies/" + this.params.id};
      }
   }
}

このルートは、上記の表で指定した機能を実行します。オブジェクトが存在する場合は、新しい詳細でオブジェクトを更新します。存在しない場合は、新しいオブジェクトが作成されます。このルートをテストするには、次のcurlコマンドを使用します。これにより、既存のムービーが更新されます。新しいムービーを作成するには、IDを存在しないIDに変更するだけです。

curl -X PUT --data "name = Toy%20story&year = 1995&rating = 8.5" 
https://localhost:3000/movies/101

応答

{"message":"Movie id 101 updated.","location":"/movies/101"}

ルートを削除

次のコードを使用して、削除ルートを作成します。

router.delete('/:id', deleteMovieWithId);

function *deleteMovieWithId(next){
   var removeIndex = movies.map(function(movie){
      return movie.id;
   }).indexOf(this.params.id); //Gets us the index of movie with given id.
   
   if(removeIndex === -1){
      this.body = {message: "Not found"};
   } else {
      movies.splice(removeIndex, 1);
      this.body = {message: "Movie id " + this.params.id + " removed."};
   }
}

他の人と同じ方法でルートをテストします。削除が成功すると(たとえばID 105)、次のようになります。

{message: "Movie id 105 removed."}

最後に、movies.jsファイルは次のようになります-

var Router = require('koa-router');
var router = Router({
   prefix: '/movies'
});  //Prefixed all routes with /movies
var movies = [
   {id: 101, name: "Fight Club", year: 1999, rating: 8.1},
   {id: 102, name: "Inception", year: 2010, rating: 8.7},
   {id: 103, name: "The Dark Knight", year: 2008, rating: 9},
   {id: 104, name: "12 Angry Men", year: 1957, rating: 8.9}
];

//Routes will go here
router.get('/', sendMovies);
router.get('/:id([0-9]{3,})', sendMovieWithId);
router.post('/', addNewMovie);
router.put('/:id', updateMovieWithId);
router.delete('/:id', deleteMovieWithId);

function *deleteMovieWithId(next){
   var removeIndex = movies.map(function(movie){
      return movie.id;
   }).indexOf(this.params.id); //Gets us the index of movie with given id.
   
   if(removeIndex === -1){
      this.body = {message: "Not found"};
   } else {
      movies.splice(removeIndex, 1);
      this.body = {message: "Movie id " + this.params.id + " removed."};
   }
}

function *updateMovieWithId(next) {
   //Check if all fields are provided and are valid:
   if(!this.request.body.name ||
      !this.request.body.year.toString().match(/^[0-9]{4}$/g) ||
      !this.request.body.rating.toString().match(/^[0-9]\.[0-9]$/g) ||
      !this.params.id.toString().match(/^[0-9]{3,}$/g)){
      
      this.response.status = 400;
      this.body = {message: "Bad Request"};
   } else {
      //Gets us the index of movie with given id.
      var updateIndex = movies.map(function(movie){
         return movie.id;
      }).indexOf(parseInt(this.params.id));
      
      if(updateIndex === -1){
         //Movie not found, create new
         movies.push({
            id: this.params.id,
            name: this.request.body.name,
            year: this.request.body.year,
            rating: this.request.body.rating
         });
         this.body = {message: "New movie created.", location: "/movies/" + this.params.id};
      } else {
         //Update existing movie
            movies[updateIndex] = {
            id: this.params.id,
            name: this.request.body.name,
            year: this.request.body.year,
            rating: this.request.body.rating
         };
         this.body = {message: "Movie id " + this.params.id + " updated.", 
            location: "/movies/" + this.params.id};
      }
   }
}

function *addNewMovie(next){
   //Check if all fields are provided and are valid:
   if(!this.request.body.name ||
      !this.request.body.year.toString().match(/^[0-9]{4}$/g) ||
      !this.request.body.rating.toString().match(/^[0-9]\.[0-9]$/g)){
      
      this.response.status = 400;
      this.body = {message: "Bad Request"};
   } else {
      var newId = movies[movies.length-1].id+1;
      
      movies.push({
         id: newId,
         name: this.request.body.name,
         year: this.request.body.year,
         rating: this.request.body.rating
      });
      this.body = {message: "New movie created.", location: "/movies/" + newId};
   }
   yield next;
}
function *sendMovies(next){
   this.body = movies;
   yield next;
}
function *sendMovieWithId(next){
   var ctx = this
   
   var currMovie = movies.filter(function(movie){
      if(movie.id == ctx.params.id){
         return true;
      }
   });
   if(currMovie.length == 1){
      this.body = currMovie[0];
   } else {
      this.response.status = 404;//Set status to 404 as movie was not found
      this.body = {message: "Not Found"};
   }
   yield next;
}
module.exports = router;

これでRESTAPIが完成しました。これで、この単純なアーキテクチャスタイルとKoaを使用して、はるかに複雑なアプリケーションを作成できます。

ロギングは、Webアプリケーションを作成するときに、どこで問題が発生したかを正確に教えてくれるので非常に便利です。また、問題が発生した場合のコンテキストを取得し、同じ解決策を考え出すことができます。

Koaでのログインを有効にするには、ミドルウェアが必要です。 koa-logger。次のコマンドを使用してインストールします。

$ npm install --save-dev koa-logger

アプリケーションで、次のコードを追加してログを有効にします。

var logger = require('koa-logger')
var koa = require('koa')

var app = koa()
app.use(logger())

app.use(function*(){
   this.body = "Hello Logger";
})

app.listen(3000)

このサーバーを実行し、サーバー上の任意のルートにアクセスします。次のようなログが表示されます。

特定のルートまたはリクエストでエラーが発生した場合、これらのログは、それぞれの問題点を特定するのに役立ちます。

足場を使用すると、簡単に作成できます。 skeleton for a web application。パブリックディレクトリを手動で作成し、ミドルウェアを追加し、個別のルートファイルを作成しました。スキャフォールディングツールは、アプリケーションの構築を直接開始できるように、これらすべてをセットアップします。

使用する足場は Yeoman。これはNode.js用に構築されたスキャフォールディングツールですが、他のいくつかのフレームワーク(フラスコ、レール、djangoなど)用のジェネレーターも備えています。yeomanをインストールするには、ターミナルで次のコマンドを入力します。

$ npm install -g yeoman

Yeomanは、ジェネレーターを使用してアプリケーションの足場を作ります。npmで利用できるyeomanで使用できるジェネレーターを確認するには、こちらにアクセスしてください。このチュートリアルでは、「generator-koa」を使用します。このジェネレーターをインストールするには、ターミナルで次のコマンドを入力します。

$ npm install -g generator-koa

このジェネレーターを使用するには、「-」と入力します。

yo koa

次に、ディレクトリ構造を作成し、次のファイルを作成します。また、必要なnpmモジュールとbowerコンポーネントもインストールされます。

create package.json
create test/routeSpec.js
create views/layout.html
create views/list.html
create public/styles/main.css
create public/scripts/.gitkeep
create controllers/messages.js
create app.js
create .editorconfig
create .jshintrc

I'm all done. Running npm install & bower install for you to install 
the required dependencies. 
If this fails, try running the command yourself.

このジェネレーターは、非常に単純な構造を作成します。

.
├── controllers
│   └── messages.js
├── public
|   ├── scripts
|   └── styles
|       └── main.css    
├── test
|   └── routeSpec.js
├── views
|   ├── layout.html
|   └── list.html
├── .editorconfig
├── .jshintrc
├── app.js
└── package.json

Koaで利用可能な多くのジェネレーターを調べて、自分に合ったジェネレーターを選択してください。すべてのジェネレーターを操作する手順は同じです。ジェネレーターをインストールし、yeomanを使用して実行する必要があります。いくつかの質問があり、回答に基づいてアプリケーションのスケルトンを作成します。

以下は、このチュートリアルの開発中に使用したリソースのリストです-

  • Koajs.com

  • Koajs-例コミュニティによって作成された例のリスト

  • 公式およびサードパーティのミドルウェアのリスト。

  • koa.jsを使用したCRUDAPI - Koa.jsでCRUDAPIを作成するための短いスクリーンキャスト

  • Koa.jsクイックスタートスクリーンキャスト

  • Koa.jsとジェネレーターの紹介