基於 Hunt Framework 3.2.0 快速構建服務端項目教程

Hunt Framework 是使用 D語言開發的全棧 Web 框架,類似於 Laravel / SpringBoot / Django 等,可以讓 D 語言開發者快速的創建項目,內置超多業務規範一是方便開發者開箱即可用,二是方便管理者對項目代碼更容易 review。

本示例代碼基於目前最新的 Hunt Framework 最新版本 3.2.0 進行編寫,接下來讓我們感受一下使用 DLang 開發的快感:)

1. 創建一個普通的模板頁面渲染項目

1.1 基於骨架項目創建空項目

首先使用 git 命令把骨架項目克隆到本地。

git clone https://github.com/huntlabs/hunt-skeleton.git myproject
cd myproject

1.2 修改項目 http 監聽地址和 監聽端口

http 相關配置項在 config/application.conf 中可以找到如下內容,我們監聽的 ip 是 127.0.0.1 端口是 8080

http.address = 127.0.0.1
http.port = 8080

1.3 控制器

我們可以看到 source/app/controller/IndexController.d 的源碼,這個就是一個普通的控制器,代碼如下:

module app.controller.IndexController;

import hunt.framework;

class IndexController : Controller
{
    mixin MakeController;

    @Action
    string index()
    {
        return view.render("index");
    }
}

我們可以看到 index 控制器還有一個 index 的方法,這個方法被使用 @Action 標記爲了可訪問的頁面,而這個頁面又使用 view 視圖渲染了 index.html 模板(這裏模板的擴展名因安全問題被省略)。

這裏的視圖會渲染 resources/views/default/index.html 模板文件。

1.4 路由配置

在配置文件目錄可以找到 config/routes 這個默認的路由配置表,骨架項目有一條記錄如下:

GET    /    index.index

這條語義是使用 GET 方法訪問 / 這個 path 會映射到 index 控制器的 index 方法。

1.5 編譯運行項目

整個項目使用 dub 包管理器管理,一個命令即可編譯運行:

dub run -v

這時候根據你自己配置的 ip 和 端口訪問即可:

http://127.0.0.1:8080

至此你的 D 語言項目就跑起來了,是不是很酷?😎那下面章節來點數據庫操作。

2 創建一個增刪改查的 API 項目

在創建增刪改查 API 之前我們需要做一些準備工作,一是創建好數據庫的表結構,二是開啓框架的路由組支持,讓用戶可以通過 example.com/api/api.example.com 的形式可以訪問到。

2.1 首先我們開啓路由組

config/application.conf 找到配置項 route.groups 修改爲:

route.groups = api:path:api

那我這裏解釋一下 api:path:api 的含義,{路由組的KEY}:{訪問路由組的方式}:{路由組的自定義值},那通過上面這個設置後我們的 api 訪問地址前綴就應該是:

http://127.0.0.1:8080/api/

如果我們設置爲 route.groups = api:domain:api.example.com 那我們訪問 api 地址的前綴就是:

http://api.example.com/

2.2 我們的表結構設計

可以自己執行這個 SQL 創建表,我們數據庫使用的是 MySQL 5.7.x 做的 example。


SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for my_user
-- ----------------------------
DROP TABLE IF EXISTS `my_users`;
CREATE TABLE `my_users` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `username` varchar(255) DEFAULT NULL,
  `password` varchar(255) DEFAULT NULL,
  `email` varchar(255) DEFAULT NULL,
  `created` bigint(11) DEFAULT NULL,
  `updated` bigint(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

SET FOREIGN_KEY_CHECKS = 1;

2.3 修改數據庫相關配置文件

數據庫配置項文件在 config/application.conf 進行修改,找到如下配置按照你自己本地數據庫環境進行設置:

# Database
database.driver = mysql
database.host = 127.0.0.1
database.port = 3306
database.database = myproject
database.username = root
database.password = 123456
database.charset = utf8
database.prefix = my_
database.enabled = true

2.4 創建數據庫模型

Hunt Framework 也是內置 Model 模型,我們創建模型類 app/model/User.d

module app.model.User;

import hunt.entity;

@Table("users")
class User : Model
{
    mixin MakeModel;

    @AutoIncrement
    @PrimaryKey
    ulong id;

    string username;
    string password;
    string email;
    
    uint created;
    uint updated;
}

要注意的是使用 @PrimaryKey 標記 id 爲主鍵,並且使用 @AutoIncrement 標記爲自增,@Table("users") 是讓你自己填寫自己表的真實名字,我們表的真實名是 my_users,因爲所有表前綴已經在 config/application.conf 中的配置項 database.prefix = my_ 配置過,所以這裏的值我們只需要寫 users 即可。

2.5 創建 Repository 對象

這個對象只要繼承 EntityRepository 即可,裏邊已經包含了很多豐富的操作方法,app/repository/UserRepository.d

module app.repository.UserRepository;

import hunt.framework;

import app.model.User;

class UserRepostiroy : EntityRepository!(User, ulong)
{

}

這裏我們自定義 UserRepository 繼承的 EntityRepositoryhunt-entity 這個 ORM 庫自帶的類,我們使用模板傳值的方式將我們自定義的 Model 類 User 和主鍵類型 ulong 傳遞過去了,這個編譯時會幫我們處理很多事情,我們只要記住如何寫就好了。

2.6 創建表單驗證的類

作爲 API 就很難缺少 POST 表單的接收和驗證,Hunt Framework 內置表單驗證機制,我們需要自己實現一個表單驗證的對象 app/form/UserForm.d

module app.form.UserForm;

import hunt.framework;

class UserForm : Form
{
    mixin MakeForm;

    @Length(4, 30, "用戶名長度必須在 {{min}} 到 {{max}} 位之間。")
    string username;

    @Length(8, 32, "密碼長度必須在 {{min}} 到 {{max}} 位之間。")
    string password;
    
    @NotEmpty("Email地址不允許爲空。")
    string email;
}

2.7 創建 API 對應的控制器

因爲我們 API 使用的是獨立的路由組,所以我們創建控制器的時候需要在 app/controller/ 目錄下再創建一個子目錄 api 來保存對應的控制器類文件,所以我們這個類文件命名爲 app/controller/api/UserController.d

module app.controller.api.UserController;

import hunt.framework;

import app.repository.UserRepostiroy;
import app.model.User;
import app.message.ResultMessage;
import app.form.UserForm;

class UserController : Controller
{
    mixin MakeController;

    @Action
    Response add(UserForm form)
    {
        // ResultMessage 是要返回的 json 消息體
        auto resultMessage = new ResultMessage;

        // 使用 valid() 方法獲取一個校驗結果對象
        auto valid = form.valid();
        if (!valid.isValid())
        {
            // 給個錯誤碼
            resultMessage.code = 10001;

            // valid.messages() 方法可以獲取所有錯誤信息,我們這裏只簡單的獲取一個錯誤進行返回
            foreach (message; valid.messages())
            {
                resultMessage.message = message;
                break;
            }
        }
        else
        {
            auto repository = new UserRepository;

            auto user = new User;
            user.username = form.username;
            user.password = form.password;
            user.email = form.email;

            // 把模型數據保存到數據庫
            repository.save(user);

            // 因沒有錯誤就不需要設置錯誤碼,提示添加成功即可
            import std.format : format;

            resultMessage.message = format!"用戶( %d )添加成功!"(user.id);
        }

        // 返回結果對象會自動由 JsonResponse 序列化爲 json 返回給客戶端
        return new JsonResponse(resultMessage);
    }
}

這裏是 ReusltMessage 的代碼: app/message/ReusultMessage.d

module app.message.ResultMessage;

class ResultMessage
{
    uint code = 0;
    string message;
}

2.8 API 路由配置文件

每個路由組有自己的路由配置表,api 的路由配置表是 config/api.routes,這個規則是不是很簡單?我們看看添加用戶接口的路由配置項:

POST    /user/add    user.add

是不是很簡單?這裏因爲是 api.routes 所以控制器會在 app/controller/api/ 目錄下找對應的 user 控制器和 add 方法。

2.9 測試添加用戶接口

這裏我們使用 Firefox 插件進行接口請求,我們按照表單的要求添加 3 個字段,分別爲 usernamepasswordemail,我們也按照 UserForm 中的驗證規則去填寫,當我們提交表單的時候可以看到如下界面:

myuser-useradd.png

這裏提示 用戶( 9 )添加成功!,這裏的數字 9 其實是我們在將用戶數據寫入庫中以後返回的主鍵 ID。

那我們爲了測試表單校驗的作用,我們把密碼從 8 位改爲 6 位,因爲我們在 UserForm 中規則設定的是 8~32 位之間,再次提交表單如下結果:

myuser-useradd-error.png

這裏說明我們的表單校驗已經起了作用:)

3 總結

最總完成的項目目錄結構如下:

MYRPOJECT/
├── config
│   ├── api.routes
│   ├── application.conf
│   └── routes
├── data
│   └── mysql.sql
├── dub.sdl
├── resources
│   ├── translations
│   │   ├── en-us
│   │   │   └── message.ini
│   │   └── zh-cn
│   │       └── message.ini
│   └── views
│       └── default
│           ├── footer.html
│           ├── header.html
│           └── index.html
├── source
│   ├── app
│   │   ├── controller
│   │   │   ├── IndexController.d
│   │   │   └── api
│   │   │       └── UserController.d
│   │   ├── form
│   │   │   └── UserForm.d
│   │   ├── message
│   │   │   └── ResultMessage.d
│   │   ├── model
│   │   │   └── User.d
│   │   └── repository
│   │       └── UserRepository.d
│   └── main.d
└── wwwroot
    └── favicon.ico

整個項目看下來也算是清晰明瞭,在框架的使用方式上有着熟悉的味道,Hunt Framework 有着像 Laravel 那麼快的開發效率,也有像 SpringBoot 那樣規範的數據庫操作方式,也具有像 golang 一樣有原生語言編譯後方便的部署方式。

相關資源地址

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章