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
繼承的 EntityRepository
是 hunt-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 個字段,分別爲 username
、password
、email
,我們也按照 UserForm
中的驗證規則去填寫,當我們提交表單的時候可以看到如下界面:
這裏提示 用戶( 9 )添加成功!
,這裏的數字 9
其實是我們在將用戶數據寫入庫中以後返回的主鍵 ID。
那我們爲了測試表單校驗的作用,我們把密碼從 8 位改爲 6 位,因爲我們在 UserForm
中規則設定的是 8~32 位之間,再次提交表單如下結果:
這裏說明我們的表單校驗已經起了作用:)
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
一樣有原生語言編譯後方便的部署方式。
相關資源地址
- HuntLabs 官方網站: https://www.huntlabs.net
- Hunt Framework 代碼庫: https://github.com/huntlabs/hunt-framework
- 完整示例代碼: https://gitee.com/zoujiaqing/example-myuser