iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 13
0
Software Development

今晚我想來點 Express 佐 MVC 分層架構系列 第 13

[今晚我想來點 Express 佐 MVC 分層架構] DAY 13 - 規劃 Express 專案

規劃之前...

不曉得大家有沒有覺得前面幾篇的教學文毫無架構可言,但還是可以做到我們要做到的事情,這是最可怕的地方,因為雜亂無序的程式碼在規模越來越大以後會變得十分難維護,就算用 再好的工具都無法拯救無架構的系統 ,如同一名武士,用再好的刀沒有技術地亂砍終究只是下級武士。為了不讓這一切成為惡夢的開端,如果不熟悉這部分的朋友請一定要看接下來的部分,它可以拯救你的!另外,接下來的實作將會以 TodoList 的 API Server 為目標來開發!

進行規劃

MVC 是一種架構的設計方式,我們會先照著 MVC 的思維來設計,但終究要走出自己的道路,來彌補 MVC 架構下的不足,這邊我先埋下伏筆,後面的篇章會再一一揭曉。

物件導向

我們會採用物件導向的方式做設計,而不是使用 Function Programming,我認為物件導向是比較好被理解的,Function Programming 相對來說比較難閱讀,而且 class 那麼香我一定用爆/images/emoticon/emoticon07.gif

檔案管理

檔案管理也是很重要的一門課,會將檔案依照某種特定的規則存放於不同資料夾中,這個分類方式因人而異,也因專案規模而異,大致上有兩種分類模式:職責分類對象分類

職責分類

這類型的分類法我認為適合用在 小型專案 以及 共用的功能模組,它是依照該程式的職責類型來做分類,舉例來說,所有 routing 相關的模組歸類於資料夾 routes 當中:

├── src
|   ├── index.ts
|   └── routes
|       ├── app.routing.ts
|       └── user.routing.ts
├── package.json
└── tsconfig.json

對象分類

這類型的分類法我認為適合用在 各種規模的專案,它將程式碼依照模組服務的對象來做分類,這麼說有點抽象,舉例來說,我們將 users 路由下特有的程式都放在這個資料夾:

├── src
|   ├── index.ts
|   └── users
|       ├── user.controller.ts
|       └── user.routing.ts
├── package.json
└── tsconfig.json

後續的實作將會以 對象分類為主、職責分類為輔 ,共用的功能模組以職責分類來維護,其餘的依照對象分類的模式來管理。

重建專案

將本來的專案目錄結構調整成下方的樣子,並清空 src 底下的 index.ts

├── src
|   ├── index.ts
|   ├── environments
|   |   ├── development.env
|   |   └── production.env
|   └── validators
|       ├── index.ts
|       └── email.validator.ts
├── package.json
└── tsconfig.json

接著我們再調整一下目錄:

├── src
|   ├── index.ts
|   ├── app.ts               // 新增的檔案
|   ├── environments
|   |   ├── development.env
|   |   └── production.env
|   └── validators
|       ├── index.ts
|       └── email.validator.ts
├── package.json
└── tsconfig.json

我們會以 index.ts 作為載入點,將 Express App 的應用程式層抽離至 app.ts,下方為 app.ts 的程式碼:

import express from 'express';
import path from 'path';
import cors from 'cors';
import helmet from 'helmet';
import dotenv from 'dotenv';

export class App {

  private app = express();

  constructor() {
    this.setEnvironment();
    this.setHelmet();
    this.setCors();
    this.registerRoute();
  }

  // ====================================================================
  // @Public Methods
  // ====================================================================

  public bootstrap(): void {
    this.app.listen(process.env.PORT, () => console.log(`API Server is running at port ${ process.env.PORT }.`));
  }

  // ====================================================================
  // @Private Methods
  // ====================================================================
  
  private setHelmet(): void {
    this.app.use(helmet());
  }

  private setCors(): void {
    this.app.use(cors());
  }

  private setEnvironment(): void {
    dotenv.config({ path: path.resolve(__dirname, `./environments/${ process.env.NODE_ENV }.env`) });
  }

  private registerRoute(): void {
    this.app.get('/', (req, res, next) => res.send('Hello!'));
  }

}

App 在建構時即註冊路由,並透過 bootstrap()啟動 Express App。

最後就是在 index.ts 中使用 App

import { App } from './app';

const bootstrap = () => {
    const app = new App();
    app.bootstrap();
};

bootstrap();

小結

今天主要就是將 Express App 的應用程式層抽離出來作為根節點,既然是整個專案的根節點,勢必就有子節點,這些子節點都會被收斂至根節點,這樣說有點太艱澀難懂了,簡單來說就是將不同層級的路由,透過路由器層的概念來切割,以便管理,那我們要怎麼切割呢?會在下一篇告訴大家。


上一篇
[今晚我想來點 Express 佐 MVC 分層架構] DAY 12 - mongoose 之 CRUD
下一篇
[今晚我想來點 Express 佐 MVC 分層架構] DAY 14 - Route Module
系列文
今晚我想來點 Express 佐 MVC 分層架構30

尚未有邦友留言

立即登入留言