Skip to content

Instantly share code, notes, and snippets.

@mitsuruog
Last active January 24, 2025 02:47
Show Gist options
  • Save mitsuruog/fc48397a8e80f051a145 to your computer and use it in GitHub Desktop.
Save mitsuruog/fc48397a8e80f051a145 to your computer and use it in GitHub Desktop.

Revisions

  1. mitsuruog revised this gist Jan 22, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion index.md
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,6 @@
    # express実践入門

    ![](https://cloud.githubusercontent.com/assets/1703219/10810636/31e3896a-7e46-11e5-85a2-a55ed87914f1.png)
    ![](https://user-images.githubusercontent.com/1703219/72898816-b0a1e500-3d1c-11ea-9fdd-62c78697f2d1.png)

    ---

  2. mitsuruog revised this gist Sep 16, 2017. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion index.md
    Original file line number Diff line number Diff line change
    @@ -1032,7 +1032,7 @@ app.set('x-powered-by', false);
    ---
    ### enjoy express :)

    ### next your turn.
    ### It’s your turn.

    ---
    ![Analytics](https://ga-beacon.appspot.com/UA-56126469-5/fc48397a8e80f051a145)
  3. mitsuruog revised this gist Oct 30, 2015. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion index.md
    Original file line number Diff line number Diff line change
    @@ -349,7 +349,9 @@ Application-level middlewareとRouter-level middlewareの違いについて、
    (後述) エラーハンドリングの部分で紹介します。

    ---
    # 中規模Webアプリケーションを構築するために
    # express開発のベストプラクティス

    中規模Webアプリケーションを構築するために必要な要素とは

    - アプリケーションのレイヤー化
    - プロジェクトストラクチャ
  4. mitsuruog revised this gist Oct 30, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion index.md
    Original file line number Diff line number Diff line change
    @@ -1033,4 +1033,4 @@ app.set('x-powered-by', false);
    ### next your turn.

    ---
    ![Analytics](https://ga-beacon.appspot.com/UA-56126469-5/fc48397a8e80f051a145?pixel)
    ![Analytics](https://ga-beacon.appspot.com/UA-56126469-5/fc48397a8e80f051a145)
  5. mitsuruog revised this gist Oct 30, 2015. 1 changed file with 4 additions and 1 deletion.
    5 changes: 4 additions & 1 deletion index.md
    Original file line number Diff line number Diff line change
    @@ -1030,4 +1030,7 @@ app.set('x-powered-by', false);
    ---
    ### enjoy express :)

    ### next your turn.
    ### next your turn.

    ---
    ![Analytics](https://ga-beacon.appspot.com/UA-56126469-5/fc48397a8e80f051a145?pixel)
  6. mitsuruog revised this gist Oct 29, 2015. 1 changed file with 2 additions and 5 deletions.
    7 changes: 2 additions & 5 deletions index.md
    Original file line number Diff line number Diff line change
    @@ -7,14 +7,11 @@
    ## 自己紹介
    ### 小川充

    - mitsuruog
    - フロントエンドエンジニア
    - Javascript, HTML, CSS, Node.js, API設計とか認証とか
    - 2015/5月入社(約半年)

    - API開発でnodeを使いたい。そのためにはnodeを使える人を増やす必要がある!!
    - JavaでAPI開発はもういやや。。。


    ---

    ## はじめに
    @@ -177,7 +174,7 @@ expressを理解する上での最小構成要素。
    ---
    ## expressの仕組み

    ![](https://dl.dropboxusercontent.com/u/77670774/tmp/slide/IMG_20151029_095825_20151029100001532.jpg)
    ![](https://cloud.githubusercontent.com/assets/1703219/10810648/6b7c795c-7e46-11e5-8ef8-7d406c68607c.jpg)

    - routing
    - 外部からのHTTP(S)リクエストに対して、内部のロジックをマッピングすること。
  7. mitsuruog revised this gist Oct 29, 2015. 1 changed file with 1 addition and 4 deletions.
    5 changes: 1 addition & 4 deletions index.md
    Original file line number Diff line number Diff line change
    @@ -1,9 +1,6 @@
    # express実践入門

    - 2015/10/29
    - 株式会社フレクト
    - テクニカルスペシャリスト
    - 小川 充
    ![](https://cloud.githubusercontent.com/assets/1703219/10810636/31e3896a-7e46-11e5-85a2-a55ed87914f1.png)

    ---

  8. mitsuruog revised this gist Oct 29, 2015. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions index.md
    Original file line number Diff line number Diff line change
    @@ -26,14 +26,14 @@

    初学者がexpressを攻略する上でのつまづくポイントと、中規模開発をターゲットにしたベストプラクティスを経験ベースでお話します。

    おそらく、〜初級者向けの内容です
    おそらく、初〜中級者向けの内容です

    ---

    ## 本コンテンツの使い方

    - express初心者
    - 初学者向けチュートリアル(dotinstallとか)のお供に
    - 初学者向けチュートリアル(dotinstallとか)のあとに
    - express経験者
    - ご自身のコードの見直しに
    - 他の言語の経験者
  9. mitsuruog revised this gist Oct 29, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion index.md
    Original file line number Diff line number Diff line change
    @@ -549,7 +549,7 @@ User.find({}}

    よく使うもの

    - find()
    - find
    - findOne
    - findById
    - findByIdAndUpdate
  10. mitsuruog revised this gist Oct 29, 2015. 1 changed file with 120 additions and 3 deletions.
    123 changes: 120 additions & 3 deletions index.md
    Original file line number Diff line number Diff line change
    @@ -497,9 +497,126 @@ Handlebarsはexpress内部のテンプレートエンジン処理のI/Fと異な
    自信がない人は近づかない方がいい(経験談)

    ---
    ## DB関連(ORMapper)
    - mongoose
    - sequalize
    ## ORM

    ORM(Object-relational mapping)この2つでOK

    - [Mongoose - elegant mongodb object modeling for node.js](http://mongoosejs.com/)
    - MongoDBならこれ
    - [Sequelize | The Node.js / io.js ORM for PostgreSQL, MySQL, SQLite and MSSQL](http://docs.sequelizejs.com/en/latest/)
    - PostgreSQL, MySQL, SQLite, MSSQL ならこれ

    ---
    ## ORM(Mongoose)

    MongooseのModelクラスを作成します。
    ```
    var mongoose = require('mongoose');
    var Schema = mongoose.Schema;
    // スキーマ定義
    var UserSchema = new Schema({
    email: {
    type: String,
    lowercase: true
    },
    password: String,
    admin: {
    type: Boolean,
    default: false
    }
    });
    // 外部に公開します
    module.exports = mongoose.model('User', UserSchema);
    ```

    ---
    ## ORM(Mongoose)

    利用するにはModelをロードして利用する。
    ```
    var User = require('./models/user.model');
    User.find({}}
    .exec()
    .then((users) => {
    // 正常系の処理
    }, (err) => {
    // 異常系の処理
    })
    ```

    よく使うもの

    - find()
    - findOne
    - findById
    - findByIdAndUpdate
    - findByOneAndUpdate
    - findByIdAndRemove
    - findByOneAndRemove
    - create
    - save

    findByIdAndUpdateではなく、findByIdしてからsaveしている方が多い気がします(経験談)

    ---
    ## ORM(Mongoose)
    Modelクラスにロジックを寄せるのが綺麗です(経験談)

    Mongoose Modelクラスの中身の例)
    ```
    var mongoose = require('mongoose');
    var Schema = mongoose.Schema;
    var UserSchema = new Schema({
    ...
    });
    //////////// Virtuals
    UserSchema
    .virtual('password')
    .set((password) => {
    this.cachedValue = password;
    // 何かのSetter処理
    })
    .get(() => { return this.cachedValue});
    //////////// Validations
    UserSchema
    .path('email')
    .validate((value) => {
    // 何かのバリデーション処理
    }, 'メッセージ');
    //////////// Hooks
    UserSchema.pre('save', (next) => {
    // 何かの処理
    return next();
    });
    //////////// Instance Methods
    UserSchema.methods = {
    authenticate(password) {
    // 何かの処理
    }
    };
    //////////// Static Methods
    UserSchema.statics = {
    findOne(id) {
    // 何かの処理
    }
    }
    module.exports = mongoose.model('User', UserSchema);
    ```

    ---
    ## ORM(Sequelize)

    さーせん!時間切れ。。。orz

    ---
    ## エラーハンドリング(1/3)
  11. mitsuruog revised this gist Oct 29, 2015. 1 changed file with 27 additions and 3 deletions.
    30 changes: 27 additions & 3 deletions index.md
    Original file line number Diff line number Diff line change
    @@ -367,7 +367,7 @@ Application-level middlewareとRouter-level middlewareの違いについて、
    - デプロイ(Heroku)

    ---
    ## プロジェクトストラクチャ(1/3)
    ## プロジェクトストラクチャ(1/4)
    ### 概要
    railsに似せた構成が好み。
    正直好みの問題です、悩みたくないならこれを使ってください(経験談)
    @@ -394,7 +394,7 @@ bower.json
    ```

    ---
    ## プロジェクトストラクチャ(2/3)
    ## プロジェクトストラクチャ(2/4)
    ### アプリケーション本体
    REST APIと画面コントローラーの置き場所は毎回悩む(経験談)
    ```
    @@ -420,7 +420,31 @@ public/
    ```

    ---
    ## プロジェクトストラクチャ(3/3)
    ## プロジェクトストラクチャ(3/4)
    ### アプリケーション設定
    設定系は小分けにする方が取り回しが良くていい。テストも楽(経験談)
    ```
    app/
    bin/
    www // サーバー起動
    config/
    environment/ // 環境設定
    .env.development
    middlewares/ // middleware置き場
    authorization.js
    errorHandler.js
    passport/ // passportのstrategy置き場
    local.js
    twitter.js
    db.js // DB関連の設定(接続先など)
    passport.js // 認証(passport)の設定
    express.js // expressサーバー本体の設定
    router.js // トップレベルのルーティング
    public/
    ```

    ---
    ## プロジェクトストラクチャ(4/4)
    ### 静的リソース

    あくまで最小構成。ViewをSPA(Single page application)にする場合は、最初からMEAN Stackを利用した方がいい(経験談)
  12. mitsuruog revised this gist Oct 29, 2015. 1 changed file with 72 additions and 4 deletions.
    76 changes: 72 additions & 4 deletions index.md
    Original file line number Diff line number Diff line change
    @@ -367,12 +367,80 @@ Application-level middlewareとRouter-level middlewareの違いについて、
    - デプロイ(Heroku)

    ---
    ## プロジェクトストラクチャ(1/3)
    ### 概要
    railsに似せた構成が好み。
    正直好みの問題です、悩みたくないならこれを使ってください(経験談)

    ```
    app/ // アプリケーション本体
    api/ // REST APIのコントローラ
    controllers/ // 画面のコントローラ
    models/ // Entiry
    repositories/ // DAO(CRUD部品)
    views/ // 画面のテンプレート
    bin/ // サーバー起動
    config/ // アプリケーションの設定系
    environment/ // 環境定義
    middlewares/ // middlewareの置き場
    passport/ // 認証系のstrategyの置き場
    express.js // express本体の設定
    router.js // トップレベルのルーティング設定
    ...js // 何かの共通設定系
    public/ // 静的リソースの置き場(js, css)
    util/ // ユーティリティ
    package.json
    bower.json
    ```

    ---
    ## プロジェクトストラクチャ(2/3)
    ### アプリケーション本体
    REST APIと画面コントローラーの置き場所は毎回悩む(経験談)
    ```
    app/ // アプリケーション本体
    api/ // REST APIのコントローラ
    users/
    index.js // /users配下のルーティング設定
    user.controller.js //
    controllers/ // 画面のコントローラ
    users/
    index.js // user画面のactionのルーティング
    user.controller.js // user画面のコントローラ
    models/ // Entiry
    user.model.js
    repositories/ // DAO(CRUD部品)
    user.repository.js
    views/ // 画面のテンプレート
    layout.jade // 共通テンプレート
    user.jade
    bin/
    config/
    public/
    ```

    ---
    ## プロジェクトストラクチャ(3/3)
    ### 静的リソース

    あくまで最小構成。ViewをSPA(Single page application)にする場合は、最初からMEAN Stackを利用した方がいい(経験談)

    ```
    app/
    bin/
    config/
    public/
    bower_modules/
    javascripts/
    stylesheets/
    package.json
    ```

    MEAN Stack)

    ** Webアプリケーションを作成するために必要なこと
    - [DaftMonk/generator-angular-fullstack](https://github.com/DaftMonk/generator-angular-fullstack)
    - [MEAN - Full-Stack JavaScript Using MongoDB, Express, AngularJS, and Node.js.](http://mean.io/#!/)

    - プロジェクトストラクチャ
    - api
    - view

    ---
    ## テンプレートエンジン
  13. mitsuruog revised this gist Oct 29, 2015. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions index.md
    Original file line number Diff line number Diff line change
    @@ -180,6 +180,8 @@ expressを理解する上での最小構成要素。
    ---
    ## expressの仕組み

    ![](https://dl.dropboxusercontent.com/u/77670774/tmp/slide/IMG_20151029_095825_20151029100001532.jpg)

    - routing
    - 外部からのHTTP(S)リクエストに対して、内部のロジックをマッピングすること。
    - middleware
  14. mitsuruog revised this gist Oct 29, 2015. 1 changed file with 0 additions and 2 deletions.
    2 changes: 0 additions & 2 deletions index.md
    Original file line number Diff line number Diff line change
    @@ -180,8 +180,6 @@ expressを理解する上での最小構成要素。
    ---
    ## expressの仕組み

    ![](https://dl.dropboxusercontent.com/u/77670774/tmp/slide/IMG_20151029_095825_20151029100001532.jpg)

    - routing
    - 外部からのHTTP(S)リクエストに対して、内部のロジックをマッピングすること。
    - middleware
  15. mitsuruog revised this gist Oct 29, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion index.md
    Original file line number Diff line number Diff line change
    @@ -180,7 +180,7 @@ expressを理解する上での最小構成要素。
    ---
    ## expressの仕組み

    「図」
    ![](https://dl.dropboxusercontent.com/u/77670774/tmp/slide/IMG_20151029_095825_20151029100001532.jpg)

    - routing
    - 外部からのHTTP(S)リクエストに対して、内部のロジックをマッピングすること。
  16. mitsuruog revised this gist Oct 28, 2015. 1 changed file with 8 additions and 6 deletions.
    14 changes: 8 additions & 6 deletions index.md
    Original file line number Diff line number Diff line change
    @@ -410,9 +410,11 @@ Handlebarsはexpress内部のテンプレートエンジン処理のI/Fと異な
    - sequalize

    ---
    ## エラーハンドリング(1/2)
    ## エラーハンドリング(1/3)

    特殊なmiddleware。expressの場合、あまり細かくtry-catchせずグローバルレベルでエラーハンドリングすることが多い。
    特殊なmiddleware。

    あまり細かくtry-catchせずグローバルレベルでエラーハンドリングすることが多い。

    ```
    function(err, req, res, next) {
    @@ -427,7 +429,7 @@ function(err, req, res, next) {
    - 画面用のレスポンス返却(エラーページ)

    ---
    ## エラーハンドリング(2/2)
    ## エラーハンドリング(2/3)
    エラーハンドリングの順番
    ```
    // エラーログ出力
    @@ -440,6 +442,9 @@ app.use('/api', clientErrorHandler);
    app.use(errorHandler);
    ```

    ---
    ## エラーハンドリング(1/3)

    エラーハンドリングの記述例
    ```
    // エラーログ出力
    @@ -464,11 +469,8 @@ function errorHandler(err, req, res, next) {
    error: err
    });
    }
    ```


    ---
    ## 認証(Passport)

  17. mitsuruog revised this gist Oct 28, 2015. 1 changed file with 62 additions and 1 deletion.
    63 changes: 62 additions & 1 deletion index.md
    Original file line number Diff line number Diff line change
    @@ -410,7 +410,63 @@ Handlebarsはexpress内部のテンプレートエンジン処理のI/Fと異な
    - sequalize

    ---
    ## エラーハンドリング
    ## エラーハンドリング(1/2)

    特殊なmiddleware。expressの場合、あまり細かくtry-catchせずグローバルレベルでエラーハンドリングすることが多い。

    ```
    function(err, req, res, next) {
    // エラー処理
    }
    ```

    最初の引数`err`にエラーの情報が連携される。基本的には次の3処理を行う。

    - エラーログ出力
    - REST API用のレスポンス返却
    - 画面用のレスポンス返却(エラーページ)

    ---
    ## エラーハンドリング(2/2)
    エラーハンドリングの順番
    ```
    // エラーログ出力
    app.use(logErrors);
    // REST API用のエラーハンドラ(ここでは、/apiがAPIの想定)
    app.use('/api', clientErrorHandler);
    // エラーベージ表示用エラーハンドラ
    app.use(errorHandler);
    ```

    エラーハンドリングの記述例
    ```
    // エラーログ出力
    function logErrors(err, req, res, next) {
    console.error(err.stack);
    next(err);
    }
    // REST API用のレスポンス返却
    function clientErrorHandler(err, req, res, next) {
    res.status(500).json({
    message: err.message,
    error: err
    });
    }
    // 画面用のレスポンス返却
    function errorHandler(err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
    message: err.message,
    error: err
    });
    }
    ```


    ---
    @@ -761,6 +817,11 @@ A: おじさんがいい方法知ってるから、後で裏に来なさい
    app.set('x-powered-by', false);
    ```

    ---
    ## まとめ

    最初はこれくらい知ってれば、まぁ大丈夫じゃないかな。

    ---
    ### enjoy express :)

  18. mitsuruog revised this gist Oct 28, 2015. 1 changed file with 4 additions and 0 deletions.
    4 changes: 4 additions & 0 deletions index.md
    Original file line number Diff line number Diff line change
    @@ -592,6 +592,10 @@ express側で値を取得する
    console.log(process.env.MONGOLAB_URI) // => http://localhost:27017
    ```

    とはいえ。。。
    [lorenwest/node-config](https://github.com/lorenwest/node-config)の方が良さそう。今度使ってみる。日々精進。


    ---
    ## セッション

  19. mitsuruog revised this gist Oct 28, 2015. 1 changed file with 17 additions and 10 deletions.
    27 changes: 17 additions & 10 deletions index.md
    Original file line number Diff line number Diff line change
    @@ -553,14 +553,27 @@ prosess.env.SOME_KEY
    ```

    ---
    ## 設定情報(dotenv)
    ## dotenv(1/2)

    [motdotla/dotenv](https://github.com/motdotla/dotenv)

    - `.env`ファイルを環境変数にマッピングする
    - ロードするファイルなどはカスタム可能

    ディレクトリ構造
    利用方法
    ```app.js
    var app = express();

    // nodeの動作環境(development/production)ごとにロードする設定情報を変更する
    require('dotenv').config({
    path: 'config/environment/.env.' + app.get('env')
    });
    ```

    ---
    ## dotenv(2/2)

    よく使うディレクトリ構造
    ```
    config
    environment
    @@ -574,14 +587,8 @@ config
    MONGOLAB_URI=http://localhost:27017
    ```

    ```app.js
    var app = express();

    // nodeの動作環境(development/production)ごとにロードする設定情報を変更する
    require('dotenv').config({
    path: 'config/environment/.env.' + app.get('env')
    });

    express側で値を取得する
    ```js
    console.log(process.env.MONGOLAB_URI) // => http://localhost:27017
    ```

  20. mitsuruog revised this gist Oct 28, 2015. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion index.md
    Original file line number Diff line number Diff line change
    @@ -430,7 +430,7 @@ Handlebarsはexpress内部のテンプレートエンジン処理のI/Fと異な
    - and more 307 Strategies

    ---
    ### Passportのフォルダ構成
    ## Passportのフォルダ構成

    - passport全体の設定 => `passport.js`
    - 個別のStrategyの設定 => `passport/`
    @@ -552,6 +552,7 @@ node.jsでの環境変数の取得方法
    prosess.env.SOME_KEY
    ```

    ---
    ## 設定情報(dotenv)

    [motdotla/dotenv](https://github.com/motdotla/dotenv)
  21. mitsuruog revised this gist Oct 28, 2015. 1 changed file with 35 additions and 5 deletions.
    40 changes: 35 additions & 5 deletions index.md
    Original file line number Diff line number Diff line change
    @@ -395,11 +395,11 @@ app.set('view engine', 'jade');
    ```

    ---
    ## テンプレートエンジン(Handlebarsの例)
    ## テンプレートエンジン(QA)

    [tj/consolidate.js](https://github.com/tj/consolidate.js)

    express内部のテンプレートエンジン処理のI/Fと異なるため、consolidateでHandlebarsをラップする必要がある
    Q:どうしても使い慣れたHandlebarsが使いたいです
    A:
    Handlebarsはexpress内部のテンプレートエンジン処理のI/Fと異なるため、[consolidate.js](https://github.com/tj/consolidate.js)でHandlebarsをラップする必要がある
    (他のJavascriptテンプレートエンジンを利用する場合も同様)

    自信がない人は近づかない方がいい(経験談)
    @@ -552,7 +552,37 @@ node.jsでの環境変数の取得方法
    prosess.env.SOME_KEY
    ```

    ##
    ## 設定情報(dotenv)

    [motdotla/dotenv](https://github.com/motdotla/dotenv)

    - `.env`ファイルを環境変数にマッピングする
    - ロードするファイルなどはカスタム可能

    ディレクトリ構造
    ```
    config
    environment
    .env.development // 開発用
    .env.production // 本番用(通常は空)
    .env.test // テスト用
    ```

    .env.development
    ```
    MONGOLAB_URI=http://localhost:27017
    ```

    ```app.js
    var app = express();

    // nodeの動作環境(development/production)ごとにロードする設定情報を変更する
    require('dotenv').config({
    path: 'config/environment/.env.' + app.get('env')
    });

    console.log(process.env.MONGOLAB_URI) // => http://localhost:27017
    ```

    ---
    ## セッション
  22. mitsuruog revised this gist Oct 28, 2015. 1 changed file with 43 additions and 6 deletions.
    49 changes: 43 additions & 6 deletions index.md
    Original file line number Diff line number Diff line change
    @@ -357,6 +357,15 @@ Application-level middlewareとRouter-level middlewareの違いについて、
    ---
    # 中規模Webアプリケーションを構築するために

    - アプリケーションのレイヤー化
    - プロジェクトストラクチャ
    - テンプレートエンジン
    - ORM
    - 共通処理
    - エラーハンドリング、認証、ロギング、セッション、設定情報
    - デリバリー
    - デプロイ(Heroku)

    ---

    ** Webアプリケーションを作成するために必要なこと
    @@ -366,19 +375,43 @@ Application-level middlewareとRouter-level middlewareの違いについて、
    - view

    ---
    ## 静的ページ
    ## テンプレートエンジン

    - [Jade - Template Engine](http://jade-lang.com/)
    - [EJS - JavaScript Templates](http://www.embeddedjs.com/)
    - Javascriptのテンプレートエンジン
    - [Handlebars.js: Minimal Templating on Steroids](http://handlebarsjs.com/)
    - [Hogan.js](http://twitter.github.io/hogan.js/)

    特にこだわりなければ、`Jade`にしておくのが最も平和(経験談)

    app.js
    ```js
    // テンプレートが格納されているフォルダを指定する
    app.set('views', path.join(__dirname, '../app/views'));

    // expressで利用するテンプレートエンジンを指定する
    app.set('view engine', 'jade');
    ```

    ---
    ## サーバーサイドレンダリング
    - Jade
    - handlebars
    ## テンプレートエンジン(Handlebarsの例)

    [tj/consolidate.js](https://github.com/tj/consolidate.js)

    express内部のテンプレートエンジン処理のI/Fと異なるため、consolidateでHandlebarsをラップする必要がある。
    (他のJavascriptテンプレートエンジンを利用する場合も同様)

    自信がない人は近づかない方がいい(経験談)

    ---
    ## DB関連(ORMapper)
    - mongoose
    - sequalize
    - エラーハンドリング

    ---
    ## エラーハンドリング


    ---
    ## 認証(Passport)
    @@ -511,7 +544,7 @@ app.use('/some', auth.authorize, (req, res) => {
    ## 設定情報

    - 動作環境ごとで異なる情報(DB接続設定、APIKey、Secret)
    - production環境の設定はリポジトリにCommitせず、動作環境の環境変数から取得する方針
    - production環境の設定はリポジトリにCommitせず、動作環境の環境変数から取得する方がいい(経験談)

    node.jsでの環境変数の取得方法

    @@ -553,6 +586,8 @@ app.use(session({
    ```js
    var app = express();
    var session = require('express-session');

    // Session Storeをロードする
    var RedisStore = require('connect-redis')(session);

    app.use(session({
    @@ -573,6 +608,8 @@ DBの接続情報は`mongoose`を利用する。(mondoDB URLでももちろん
    ```js
    var app = express();
    var session = require('express-session');

    // Session Storeをロードする
    var MongoStore = require('connect-mongo')(session);
    var mongoose = require('mongoose');

  23. mitsuruog revised this gist Oct 28, 2015. 1 changed file with 10 additions and 10 deletions.
    20 changes: 10 additions & 10 deletions index.md
    Original file line number Diff line number Diff line change
    @@ -526,16 +526,6 @@ prosess.env.SOME_KEY

    [expressjs/session](https://github.com/expressjs/session)

    - Session IDがcookieに保存される
    - デフォルトのSession ID名は`connect.sid`
    - デフォルトはオンメモリ上で保持される。通常はSession Storesで永続化する

    Session Stores)
    - [tj/connect-redis](https://github.com/tj/connect-redis) - redis用
    - [kcbanner/connect-mongo](https://github.com/kcbanner/connect-mongo) - mongodb用
    - [mweibel/connect-session-sequelize](https://github.com/mweibel/connect-session-sequelize) - postgress, mssqlなどRDB用
    - and more ...

    ```js
    var app = express();
    var session = require('express-session');
    @@ -547,6 +537,16 @@ app.use(session({
    }));
    ```

    - Session IDがcookieに保存される
    - デフォルトのSession ID名は`connect.sid`
    - デフォルトはオンメモリ上で保持される。通常はSession Storesで永続化する

    Session Stores)
    - [tj/connect-redis](https://github.com/tj/connect-redis) - redis用
    - [kcbanner/connect-mongo](https://github.com/kcbanner/connect-mongo) - mongodb用
    - [mweibel/connect-session-sequelize](https://github.com/mweibel/connect-session-sequelize) - postgress, mssqlなどRDB用
    - and more ...

    ---
    ## セッション(Redis Session Store)

  24. mitsuruog revised this gist Oct 28, 2015. No changes.
  25. mitsuruog revised this gist Oct 28, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion index.md
    Original file line number Diff line number Diff line change
    @@ -521,7 +521,7 @@ prosess.env.SOME_KEY

    ##


    ---
    ## セッション

    [expressjs/session](https://github.com/expressjs/session)
  26. mitsuruog revised this gist Oct 28, 2015. 1 changed file with 92 additions and 6 deletions.
    98 changes: 92 additions & 6 deletions index.md
    Original file line number Diff line number Diff line change
    @@ -255,6 +255,8 @@ router.get('/', (req, res) => {
    - リクエストパラメータのkey-valueペア
    - req.get
    - HTTPヘッダーの値を取得する
    - req.session
    - セッションのkey-valueペア(express-session middlewareが必要)

    ---
    ## routing(Response method)
    @@ -520,8 +522,95 @@ prosess.env.SOME_KEY
    ##


    - セッション
    - ロギング
    ## セッション

    [expressjs/session](https://github.com/expressjs/session)

    - Session IDがcookieに保存される
    - デフォルトのSession ID名は`connect.sid`
    - デフォルトはオンメモリ上で保持される。通常はSession Storesで永続化する

    Session Stores)
    - [tj/connect-redis](https://github.com/tj/connect-redis) - redis用
    - [kcbanner/connect-mongo](https://github.com/kcbanner/connect-mongo) - mongodb用
    - [mweibel/connect-session-sequelize](https://github.com/mweibel/connect-session-sequelize) - postgress, mssqlなどRDB用
    - and more ...

    ```js
    var app = express();
    var session = require('express-session');

    app.use(session({
    secret: 'secret-key',
    resave: false,
    saveUninitialized: true
    }));
    ```

    ---
    ## セッション(Redis Session Store)

    ```js
    var app = express();
    var session = require('express-session');
    var RedisStore = require('connect-redis')(session);

    app.use(session({
    secret: 'secret-key',
    resave: true,
    saveUninitialized: true,
    // Session Storeの設定
    store: new RedisStore({
    url: <REDIS_URL> // redis://localhost:6379
    })
    }));
    ```

    ---
    ## セッション(MongoDB Session Store)

    DBの接続情報は`mongoose`を利用する。(mondoDB URLでももちろん可)
    ```js
    var app = express();
    var session = require('express-session');
    var MongoStore = require('connect-mongo')(session);
    var mongoose = require('mongoose');

    app.use(session({
    secret: 'secret-key',
    resave: true,
    saveUninitialized: true,
    // Session Storeの設定
    store: new mongoStore({
    mongooseConnection: mongoose.connection
    })
    }));
    ```

    ---
    ## ロギング

    [expressjs/morgan](https://github.com/expressjs/morgan)

    - アクセスログを出力する
    - 出力先は標準出力(ファイル出力&ローテション可能)
    - expressに求める機能が薄いためなのか、今のところこれで十分(経験談)

    app.js
    ```js
    var logger = require('morgan');
    // ログフォーマット
    // combined, common, dev, short, tiny
    app.use(logger('dev'));
    ```

    出力内容
    ```
    PUT /api/articles/5621dc5633d2c52b7c166873 500 12.569 ms - 47
    GET /new-post 200 771.074 ms - 1885
    GET /stylesheets/style.css 200 13.891 ms - 102
    GET /bower_components/bootstrap/dist/css/bootstrap-theme.min.css 200 18.804 ms - 23357
    ```

    ---
    ## デプロイ(Heroku)
    @@ -581,12 +670,9 @@ package.json
    ---
    ## デプロイ(Heroku Q&A)

    Q: augularとか使っているので、gulpでビルドをしたいです
    Q: augularとか使っているので、gulpでビルドをしたいです
    A: おじさんがいい方法知ってるから、後で裏に来なさい

    ---
    - 起動、監視

    ---
    ## 小ネタ

  27. mitsuruog revised this gist Oct 28, 2015. 1 changed file with 7 additions and 3 deletions.
    10 changes: 7 additions & 3 deletions index.md
    Original file line number Diff line number Diff line change
    @@ -413,7 +413,7 @@ config
    ```

    ---
    ## passportの使い方(1/3)
    ## Passportの使い方(1/3)

    passportモジュールの読み込み。Session用のmiddlewareの設定。

    @@ -430,7 +430,7 @@ app.use(passport.session());
    ```

    ---
    ## passportの使い方(2/3)
    ## Passportの使い方(2/3)
    Passport全体の設定。sessionのserializer/deserializer&利用するStrategyの設定

    config/passport.js
    @@ -458,7 +458,7 @@ module.exports = () => {
    ```

    ---
    ## passportの使い方(3/3)
    ## Passportの使い方(3/3)
    Strategyの個別設定。
    (※)詳細はそれぞれのStrategyの公式ページを参照してください。

    @@ -490,6 +490,7 @@ passportの作者が作ったものがある。
    [connect-ensure-login](https://github.com/jaredhanson/connect-ensure-login)

    予めmiddleware化しておく。

    config/middlewares/authorization.js
    ```js
    // 認証フィルタに引っかかると`/badLoginRedirectPath`にリダイレクト
    @@ -577,6 +578,9 @@ package.json
    }
    ```

    ---
    ## デプロイ(Heroku Q&A)

    Q: augularとか使っているので、gulpでビルドをしたいです
    A: おじさんがいい方法知ってるから、後で裏に来なさい

  28. mitsuruog revised this gist Oct 28, 2015. 1 changed file with 64 additions and 4 deletions.
    68 changes: 64 additions & 4 deletions index.md
    Original file line number Diff line number Diff line change
    @@ -466,6 +466,7 @@ config/passport/local.js
    ```js
    // Strategyをロードする
    var LocalStrategy = require('passport-local').Strategy;

    // Strategyことの認証ロジックを追加する
    module.exports = new LocalStrategy({
    // 認証ロジック
    @@ -503,26 +504,86 @@ app.use('/some', auth.authorize, (req, res) => {
    });
    ```

    ---
    ## 設定情報

    - 動作環境ごとで異なる情報(DB接続設定、APIKey、Secret)
    - production環境の設定はリポジトリにCommitせず、動作環境の環境変数から取得する
    - production環境の設定はリポジトリにCommitせず、動作環境の環境変数から取得する方針

    node.jsでの環境変数の取得方法

    ```
    prosess.env.SOME_KEY
    ```

    ##


    - セッション
    - ロギング
    - デプロイ(Heroku)
    - 起動、監視

    ---
    ## デプロイ(Heroku)

    ```
    git push heroku master
    ```

    - Herokuの話
    - アプリケーション直下に`package.json`があるとNode.jsと判定される。
    - node.js場合、`npm run start`が自動実行される。(Procfile必要なし)

    package.json
    ```
    {
    "name": "node-sample",
    "version": "0.0.0",
    "private": true,
    "scripts": {
    "start": "node ./bin/www" ← これ
    },
    "dependencies": {
    "body-parser": "~1.13.2",
    "cookie-parser": "~1.3.5",
    ...
    }
    }
    ```

    ---
    ## デプロイ(Heroku Q&A)

    Q: bowerモジュールがインストールされません
    A: package.jsonのdependenciesにbowerを追加して`postinstall`する

    [ECMAScript 6で開発したアプリをHerokuにデプロイ - フレクトのHeroku Lab](http://blog.flect.co.jp/labo/2015/07/ecmascript-6her-ec6a.html)

    package.json
    ```
    {
    "name": "node-sample",
    "version": "0.0.0",
    "private": true,
    "scripts": {
    "start": "node ./bin/www",
    "postinstall": "bower install" ← これ
    },
    "dependencies": {
    "body-parser": "~1.13.2",
    "cookie-parser": "~1.3.5",
    "bower": "^1.6.3", ← これ
    ...
    }
    }
    ```

    Q: augularとか使っているので、gulpでビルドをしたいです
    A: おじさんがいい方法知ってるから、後で裏に来なさい

    ---
    - 起動、監視

    ---
    ## 小ネタ

    レスポンスの`x-powered-by`ヘッダーを消す。
    @@ -532,7 +593,6 @@ app.set('x-powered-by', false);
    ```

    ---

    ### enjoy express :)

    ### next your turn.
  29. mitsuruog revised this gist Oct 28, 2015. 1 changed file with 12 additions and 7 deletions.
    19 changes: 12 additions & 7 deletions index.md
    Original file line number Diff line number Diff line change
    @@ -397,12 +397,16 @@ Application-level middlewareとRouter-level middlewareの違いについて、
    ---
    ### Passportのフォルダ構成

    - passport全体の設定 => `passport.js`
    - 個別のStrategyの設定 => `passport/`
    - 認証フィルタはmiddleware化する

    ```
    config
    app.js - passportの初期化
    passport.js - sessionのserialize/deserialize、利用するStrategyの設定
    passport/ - Strategyごとの認証ロジック
    local.js - Username and password用
    passport.js - passportの全体的な設定
    passport/ - Strategyごとの認証ロジックの設定
    local.js - Username and password認証用
    twitter.js - twitter認証用
    middlewares
    authorization.js - routingで利用する認証フィルタ
    @@ -411,7 +415,7 @@ config
    ---
    ## passportの使い方(1/3)

    Session用のmiddlewareを設定する
    passportモジュールの読み込み。Session用のmiddlewareの設定

    app.js
    ```js
    @@ -427,7 +431,7 @@ app.use(passport.session());

    ---
    ## passportの使い方(2/3)
    Session利用のための設定(続き)&利用するStrategyを設定する
    Passport全体の設定。sessionのserializer/deserializer&利用するStrategyの設定

    config/passport.js
    ```js
    @@ -448,15 +452,15 @@ module.exports = () => {

    // 利用するstrategyを設定
    passport.use(require('./passport/local'));
    passport.use(require('./passport/twitter'));
    ...

    }
    ```

    ---
    ## passportの使い方(3/3)
    Strategyの個別設定を行う
    Strategyの個別設定。
    (※)詳細はそれぞれのStrategyの公式ページを参照してください。

    config/passport/local.js
    ```js
    @@ -473,6 +477,7 @@ module.exports = new LocalStrategy({
    app.post('/login',
    passport.authenticate('local', { failureRedirect: '/login' }),
    function(req, res) {
    // 認証成功時
    res.redirect('/');
    });
    ```
  30. mitsuruog revised this gist Oct 28, 2015. 1 changed file with 36 additions and 30 deletions.
    66 changes: 36 additions & 30 deletions index.md
    Original file line number Diff line number Diff line change
    @@ -350,8 +350,7 @@ Application-level middlewareとRouter-level middlewareの違いについて、
    ## middleware(Error-handling)
    ### Error-handling

    (後述)
    エラーハンドリングの部分で紹介します。
    (後述) エラーハンドリングの部分で紹介します。

    ---
    # 中規模Webアプリケーションを構築するために
    @@ -364,28 +363,39 @@ Application-level middlewareとRouter-level middlewareの違いについて、
    - api
    - view

    - 静的ページ
    - サーバーサイドレンダリング
    ---
    ## 静的ページ


    ---
    ## サーバーサイドレンダリング
    - Jade
    - handlebars
    - DB関連(ORMapper)

    ---
    ## DB関連(ORMapper)
    - mongoose
    - sequalize
    - エラーハンドリング

    ## 認証
    ---
    ## 認証(Passport)

    passport
    [Passport](http://passportjs.org/)

    豊富なStrategyがあり、様々な認証に対応可能
    - ほぼ、node.jsの認証モジュールでデファクト
    - 様々な認証に対応可能(Strategy)
    - 下手に独自で認証を実装するくらいなら、Passportの使い方を習得したほうが後々潰しが効く(経験談)

    対応例)
    - [passport-local](https://github.com/jaredhanson/passport-local) - Username and password
    - [passport-twitter](https://github.com/jaredhanson/passport-twitter) - Twitter
    - [passport-facebook](https://github.com/jaredhanson/passport-facebook) - Facebook
    - [passport-google-oauth](https://github.com/jaredhanson/passport-google-oauth) - Google
    - and more 307 Strategies

    ### よく使うフォルダ構成
    ---
    ### Passportのフォルダ構成

    ```
    config
    @@ -398,20 +408,25 @@ config
    authorization.js - routingで利用する認証フィルタ
    ```

    ### passportの基本的な使い方
    ---
    ## passportの使い方(1/3)

    Session用のmiddlewareを設定する。

    app.js
    ```js
    var passport = require('passport');

    // passportモジュールをLoad
    require('./passport')(app);

    // session用のmiddlewaresを有効化
    app.use(passport.initialize());
    app.use(passport.session());
    ```

    ---
    ## passportの使い方(2/3)
    Session利用のための設定(続き)&利用するStrategyを設定する

    config/passport.js
    @@ -422,6 +437,7 @@ module.exports = () => {
    passport.serializeUser((user, done) => {
    done(null, user.id);
    });

    // sessionからユーザー情報を復元する処理
    passport.deserializeUser((id, done) => {
    // DBのUserテーブルからユーザーを取得する処理
    @@ -438,30 +454,17 @@ module.exports = () => {
    }
    ```

    ---
    ## passportの使い方(3/3)
    Strategyの個別設定を行う

    config/passport/local.js
    ```js
    // Strategyをロードする
    var LocalStrategy = require('passport-local').Strategy;

    // Strategyことの認証ロジックを追加する
    module.exports = new LocalStrategy({
    usernameField: 'email',
    passwordField: 'password'
    }, (email, password, done) => {
    // Userテーブルからデータを取得する処理を追加
    User.findOne({
    email: email,
    password: password
    })
    .exec()
    .then((user) => {
    // 認証OKの場合
    return done(null, user);
    }, (err) => {
    // 認証NGの場合
    return done(err);
    });

    // 認証ロジック
    });
    ```

    @@ -474,17 +477,20 @@ app.post('/login',
    });
    ```

    ### 認証フィルタ
    ---
    ## Passport(認証フィルタ)

    passportの作者が作ったものがある。
    [connect-ensure-login](https://github.com/jaredhanson/connect-ensure-login)

    予めmiddleware化しておく。
    config/middlewares/authorization.js
    ```js
    // 認証フィルタに引っかかると`/badLoginRedirectPath`にリダイレクト
    exports.authorize = require('connect-ensure-login').ensureLoggedIn('/badLoginRedirectPath');
    ```

    routing側での利用方法
    routingでmiddlewareを設定する
    ```js
    var auth = require('middlewares/authorization');
    app.use('/some', auth.authorize, (req, res) => {