-
-
Notifications
You must be signed in to change notification settings - Fork 10
Connectの仕組み #60
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Connectの仕組み #60
Changes from 10 commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
089c2af
Connectの仕組み
azu 8cb4914
feat(connect): middlewareをtraceするサンプルを追加
azu b97fb1c
feat(connect): middlewareについて
azu 88e6f18
feat(connect): 簡単なしくみについてを追加
azu 7bbc99c
fix(connect): Lintの結果を修正
azu 1a5fd36
fix(connect): remove unused http module
azu 2337d17
chore(connect): stackの保持についてを修正
azu ad819cb
chore(connect): 文章の視点がコロコロ変わっていたのを修正
azu 1d51181
chore(connect): errorHandlingは例外フローとして分ける
azu eaad6be
chore(connect): Rackを参考にしてると思える理由の文章を改善
azu 712a4f2
chore(connect): をが重なってるのを修正
azu ef91224
chore(connect): いきなり結論が書かれていたのを修正
azu db48a29
chore(connect): 脱字を修正
azu 230f403
chore(connet): add break line
azu 4ae56e4
chore(connect): より具体的な処理に変更
azu 5d460d0
chore(connect): このようなが連続していた
azu c521902
chore(connect): 〆を修正
azu File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,7 +23,7 @@ Echoサーバとは、送られてきたリクエストの内容をそのまま | |
``` | ||
|
||
`app.use(middleware)` という形で、_middleware_と呼ばれる関数には`request`や`response`といったオブジェクトが渡されます。 | ||
そのため、リクエストみてフィルタリングしたり、任意のレスポンスを返したり出来るようになっています。 | ||
この`request`や`response`を_middleware_で処理することでログを取ったり、任意のレスポンスを返したり出来るようになっています。 | ||
|
||
Echoサーバでは `req.pipe(res);` という形でリクエストをそのままレスポンスとして流す事で実現されています。 | ||
|
||
|
@@ -47,4 +47,68 @@ Echoサーバでは `req.pipe(res);` という形でリクエストをそのま | |
基本的にどの_middleware_も`app.use(middleware)`という形で拡張でき、 | ||
モジュールとして実装すれば再利用もしやすい形となっています。 | ||
|
||
> **Note** _middleware_となる関数の引数が4つであると、それはエラーハンドリングの_middleware_とするという、Connectの独自のルールがあります。 | ||
> **Note** _middleware_となる関数の引数が4つであると、それはエラーハンドリングの_middleware_とするという、Connect独自のルールがあります。 | ||
|
||
## どういう仕組み | ||
|
||
Connectの_middleware_がどのような仕組みで動いているのかを見ていきます。 | ||
|
||
`app`に登録した_middleware_は、リクエスト時に呼び出されています。 | ||
そのため、`app`のどこかに利用する_middleware_を保持していることは推測できると思います。 | ||
|
||
Connectでは`app.stack`に_middleware_を配列として保持しています。 | ||
次のようにして`app.stack`の中身を表示見ることで、_middleware_が登録順で保持されていることがわかります。 | ||
|
||
[import connect-trace-example.js](../../src/connect/connect-trace-example.js) | ||
|
||
後は、サーバがリクエストを受け取った時に、それぞれの_middleware_を順番に呼び出しています。 | ||
|
||
上記の例だと以下の順番で_middleware_が呼び出されることになります。 | ||
|
||
- errorHandler | ||
- nosniff | ||
- hello | ||
|
||
エラーハンドリングの_middleware_は処理中にエラーが起きた時のみ呼ばれます。 | ||
そのため、通常は [nosniff.js](#nosniff.js) -> [hello.js](#hello.js) の順で呼び出されます。 | ||
|
||
[import nosniff.js](../../src/connect/nosniff.js) | ||
|
||
`nosniff.js`は、処理が終わったら`next()`を呼び出していて、 | ||
この`next()`が次の_middleware_へ行くという意味になります。 | ||
|
||
次に、`hello.js`を見てみると、`next()`がないことがわかります。 | ||
|
||
[import hello.js](../../src/connect/hello.js) | ||
|
||
`next()`がないということは`hello.js`がこの連続する_middleware_の最後となっていることがわかります。 | ||
仮に、これより先に_middleware_が登録されていたとしても無視されます。 | ||
|
||
つまり、処理的には以下のようにstackを先頭から一個づつ取り出して、処理していくという方法が取られています。 | ||
|
||
```js | ||
let req = "...", | ||
res = "..."; | ||
function next(){ | ||
let middleware = app.stack.shift(); | ||
// nextが呼ばれれば次のmiddleware | ||
middleware(req, res, next); | ||
} | ||
next();// 初回 | ||
``` | ||
|
||
|
||
このような_middleware_を繋げた形を_middleware stack_と呼ぶことがあります。 | ||
|
||
このような_middleware stack_で構成されるHTTPサーバとして、 | ||
PythonのWSGI MiddlewareやRubyのRackなどが該当します。 | ||
|
||
ConnectはRackと同じく`use`で_middleware_を指定することからも分かりますが、 | ||
Rackを参考にして実装されています。 | ||
|
||
- [Ruby - Rack解説 - Rackの構造とRack DSL - Qiita](http://qiita.com/higuma/items/838f4f58bc4a0645950a#2-5 "Ruby - Rack解説 - Rackの構造とRack DSL - Qiita") | ||
|
||
次に、この_middleware stack_をどう処理しているのかを、 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. を を となってる |
||
具体的な実装を書きながら見て行きましょう。 | ||
|
||
## 実装してみよう |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
"use strict"; | ||
import errorHandler from "./errorHandler"; | ||
import hello from "./hello"; | ||
import nosniff from "./nosniff"; | ||
import connect from "connect"; | ||
|
||
const responseText = "response text"; | ||
let app = connect(); | ||
// add Error handling | ||
app.use(errorHandler()); | ||
// add "X-Content-Type-Options" to response | ||
app.use(nosniff()); | ||
// respond to all requests | ||
app.use(hello(responseText)); | ||
|
||
// print middleware list | ||
app.stack.map(({handle}) => console.log(handle)); | ||
/* => | ||
[Function: errorHandling] | ||
[Function: nosniff] | ||
[Function: hello] | ||
*/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
"use strict"; | ||
export default function (text) { | ||
return function (req, res) { | ||
return function hello(req, res) { | ||
res.end(text); | ||
}; | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
このような_middleware stack_を作って使うものは => HTTPサーバ => 設計思想として