
該存儲庫包含基於HTMX(Frontend)和Drogon C ++框架(後端)的HDA。
目的是在不使用任何常規JavaScript框架的情況下創建一個響應迅速的“ Web應用程序”。
這個項目的想法是在閱讀出色的書籍HyperMedia系統時。在其中,作者談論編寫modern Web應用程序的替代方法。與大多數有關Web開發的書籍不同,作者不依賴任何JavaScript框架,而是回到the web本身的HyperMedia體系結構的根源。
我還寫了一篇有關該項目的文章以及使用HTMX和C ++的一般動機。
作者沒有使用JavaScript克服HTML,這種策略基本上是重現了90ES的厚信息,而是使用htmx來增強它。他們使它能夠做更多的事情,而不會恢復到聰明的JavaScript技巧。當然,JS並非禁止, htmx本身依賴於它自己的發展,但是JS並不可見,因為沒有實際的需求。
我們不需要使用JS來替換看似“不足”的超媒體控件,因為HTMX在這裡擴展它們。它使他們能夠按照最初的定義做更多的工作。例如,可以“升級”錨標籤( <a> ),以便可以執行發布,放置,修補甚至刪除請求。 <form>標籤不必是通過發布請求發送數據的唯一HyperMedia控件。編寫自己的控件如何完全一樣?還是可以修補服務器上現有條目的<form> s?通常,通常可以通過升級的HyperMedia控件來聲明地進行明確的JS代碼。
這是這個項目的一個示例。兩個按鈕(取消和保存)幾乎可以在每個足夠複雜的Web應用程序中找到。
< button hx-get =" /contacts "
hx-target =" #main "
hx-swap =" innerHTML " >
Cancel
</ button >
< button hx-post =" /contacts/{%contact.ID%}/edit "
hx-include =" input "
hx-target =" #main "
hx-swap =" innerHTML " >
Save
</ button >信不信由你,但是這兩個都利用以下功能:
<button>控件的HTTP動詞。而且不需要單行的JavaScript才能使其正常工作。這就是HyperMedia架構的實際功能。
我們還使用_hyperscript,一個小庫進行事件處理和DOM操縱。有了它,我們可以聆聽和派遣事件,操縱DOM對象,而無需離開HTML。
這是這個項目的一個示例:
< button id =" edit-c " class =" btn btn-primary "
hx-get =" /contacts/{%c.ID%}/edit "
hx-target =" #main "
hx-swap =" innerHTML " > Edit </ button >
< button class =" btn btn-danger "
hx-delete =" /contacts/{%c.ID%}/delete "
hx-confirm =" Are you sure you wish to delete this contact? "
hx-target =" this "
hx-swap =" none "
_ =" on click remove #edit-c
then remove me "
> Delete </ button >
< button class =" btn btn-info "
hx-get =" /contacts "
hx-target =" #main "
hx-swap =" innerHTML " > Back </ button >在第二個<button>控制中,我們有幾個_hyperscript執行以下操作:
最終結果是刪除按鈕Edit和Delete 。只有按鈕Back 。

我們可以將HTML使用為最初設計的HTML來來回發送JSON(並且每次根據某些內部邏輯進行解析):作為有意義的HyperMedia應用程序的工具。 HTTP協議是由於HTML而存在的,但是如今,我們主要將JSON轉移到了它上。這實際上沒有任何意義,因為JSON無法運輸應用程序語義,這有效地削弱了網絡客戶服務器考古的原始含義。難怪我們在前端上需要大量的JS框架,因為我們的服務器大多只是帶有JSON API的數據提供商。而Json Apis並不是“安息”。
該書的示例後端源代碼是用Python編寫的,可以使用它代替C ++。實際上,我試圖模仿原始的python apis,因此在理解它們兩者方面都不應該存在很大的差距。閱讀各個章節時,我正在編寫C ++代碼。
但是,由於htmx是非常不可知論的,因此使用任何語言都沒有問題,因此我使用了C ++。從學習的角度來看,這也很好,因為它迫使我仔細檢查所有內容。
我認為,我們不僅應該從前端中消除膨脹(在此處放置任何龐大的JS框架),而且還應該從我們的後端(將任何巨大的後端框架放在這裡)消除。大量軟件會消耗大量的時間和精力。人類的時間和能量以及CPU週期和電力。
需要一些C ++庫才能成功。該項目使用VCPKG作為其軟件包管理器,但是您可以自由選擇其他任何東西。
要vcpkg install PACKAGE_NAME install package_name即可。
需要以下包裝:
drogon
drogon[ctl]
fmt
argparse
brotli
zlib
openssl
sqlite3
soci[core]
soci[sqlite3]
對它們的搜索很容易: vcpkg search PACKAGE_NAME
sudo apt install uuid-dev libcriterion-dev
Windows用戶將必須首先設置MSYS環境。安裝後,在Windows開始菜單中選擇MSYS2 MINGW64條目。請勿使用MSYS UCRT4或任何其他條目!
在新打開的bash窗口中,輸入此命令以安裝所需的軟件包:
pacman -S git mingw-w64-x86_64-gcc mingw-w64-x86_64-cmake make mingw-w64-x86_64-c-ares mingw-w64-x86_64-jsoncpp mingw-w64-x86_64-openssl
檢查編譯器是否可用於which g++ 。您應該看到這樣的消息:
$ which g++
/mingw64/bin/g++您還需要一個編輯器來更新環境路徑,因此請安裝您的首選,例如pacman -Sy nano或pacman -Sy vim
用nano打開您的.bash_profile nano .$HOME/.bash_profile ,並將這三行添加到文件末尾:
PATH=/mingw64/bin: $PATH
export VCPKG_DEFAULT_TRIPLET=x64-mingw-static
export VCPKG_DEFAULT_HOST_TRIPLET=x64-mingw-static保存並關閉文件。重新加載它: source $HOME/.bash_profile或. ~/.bash_profile
稍後將需要兩個三重列條目,以指示vcpkg使用mingw而不是默認的Visual C ++編譯器。而且,由於我們也只想編譯靜態庫,因此我們通過使用static後綴宣布它。
與其他軟件包不同,Drogon不會使用vcpkg安裝。當前可用的VCPKG軟件包THWOS彙編錯誤,這就是我們必須手動編譯它的原因。
克隆Drogon來源並準備構建環境。以下示例的/c/bin/drogon路徑應適用於您的本地設置。此路徑的根( /c/bin )必須映射到Windows系統中已經存在的路徑,例如C:/bin或您選擇的任何其他路徑。
git clone https://github.com/drogonframework/drogon --recursive
mkdir drogon/build
cd drogon/build
cmake .. -G " MSYS Makefiles " -DCMAKE_INSTALL_PREFIX:PATH=/c/bin/drogon現在,用make -j編譯Drogon,然後等到完成。
最後,使用make install安裝Drogon。
現在,您應該查看C:/bin/drogon中的文件夾列表。

第二步是安裝一些將在靜態上鍊接的庫。我們將使用vcpkg來編譯它們。
從同一bash窗口中,將以下命令發佈到設置vcpkg 。
cd $HOME
git clone https://github.com/microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.bat注意:
If you pefer to install vcpkg files under different root path, change the first command "cd $HOME" from the script above.
For example: cd /c/Users/WINDOWS_USER_NAME
In MSYS Bash, the Windows file system is located under /c.
And your MSYS $HOME folder is located under "home" in your Windows MSYS root folder.
在vcpkg文件夾中,發出以下命令以安裝所需庫:
./vcpkg.exe install argparse
./vcpkg.exe install fmt
./vcpkg.exe install brotli
./vcpkg.exe install zlib
./vcpkg.exe install openssl
./vcpkg.exe install sqlite3
./vcpkg.exe install soci
./vcpkg.exe install soci[sqlite3]現在,您可以使用./buildall.ps1通過Poweshell編譯該項目。
但是,不要忘記在meson.build中更改vcpkg_root 。該路徑應指向先前的克隆vcpkg存儲庫。

我選擇的構建系統是Meson,因為Makefiles很難維護,我根本不想學習如何使用CMake 。對於用戶敵對軟件而言,生活太短了。
有兩個腳本, buildall.sh (macos/linux)和buildall.ps1 (Windows)。通過這兩個步驟將執行以下步驟:
builddir (僅在Windows,在MacOS/Linux中,這將由Meson完成)drogon_ctl將CSP轉換為C ++源文件,並將其放入src/viewssrc編譯來源builddir需要C ++ 20編譯器。我正在使用GNU C ++ v12.1.0。
在嘗試構建項目之前,請在meson.build文件中調整這兩個變量:
該triplet帶有有關主機機器的信息,例如x64-osx 。
vcpkg_root是包含vcpkg安裝的軟件包的根文件夾。
Meson將使用drogon_ctl將CSP模板轉換為C ++文件。

前端使用HTMX庫和一些Bootstrap資源來進行樣式。由於HTMX已經提供了我們期望任何modern網絡應用程序提供的responsive東西,因此沒有手寫的JavaScript運行。
後端基於非常快速的C ++ Web框架,稱為Drogon 。
使用的數據庫是SQLITE3,但可以輕鬆地用任何其他SQL數據庫替換。只需調整src/database/db_mgr.cpp類即可。用於訪問SQLite3的庫是SOCI,它支持許多其他數據庫後端。該項目的根包含該應用程序默認使用的SQLite3文件demo.db還有一個可用的CSV文件contacts.csv ,其中包含一些條目,可用於填充新表。

controllers包含Drogon用來將客戶端調用映射到後端功能的類。database包含一個小型包裝類,用於訪問SQLITE3實例。dtos包含用於在前端和後端之間用於數據Tansfers的Data Transfer Objects 。templates包含CSP(C ++服務器頁面),這些模板是drogon_ctl用於生成C ++源的模板。這些來源將用於創建HTML輸出。views包含Drogon生成的C ++類。這些文件不應手動編輯。它們將在每個構建中被替換。要更改其行為或內容,請改用templates文件夾中的CSP。 測試是使用標準庫進行的。
標準可以通過brew install criterion安裝。否則,您可以按照此處描述的方式手動構建它。
要與Meson建立標準,請首先克隆它的回購:
git clone --recursive https://github.com/Snaipe/Criterion.git然後發出以下命令:
cd Criterion
meson - Dprefix = c: / bin / criterion build
ninja - C build install可以更改安裝目錄前綴。安裝完成後,為Criterion的DLL文件設置路徑。該DLL將由具有標準鏈接的測試可執行文件使用。

該項目的測試來源位於test中,並由Meson自動構建。要執行測試,您可以使用以下兩個選項:
PS > meson test - C .builddir
ninja: no work to do .
ninja: Entering directory ` .builddir '
ninja: no work to do.
1/1 basic OK 0.09s
Ok: 1
Expected Fail: 0
Fail: 0
Unexpected Pass: 0
Skipped: 0
Timeout: 0
Full log written to .builddirmeson-logstestlog.txt或直接調用測試本身:
PS > .builddir test_demo_web_server.exe
[ ==== ] Synthesis: Tested: 1 | Passing: 1 | Failing: 0 | Crashing: 0 Web應用程序首先加載index.html ,其中包含一個帶有ID =“ main”的div標籤。在整個應用程序中,其他控件將使用此標籤來動態替換其內容,而無需任何頁面刷新。但是,與其他典型的modern Web應用程序不同,我們不使用諸如React或Angular之類的JS框架來響應該應用程序。相反,我們僅將htmx用作腳本庫。
還涉及三個bootstrap資源,但這只是使應用看起來更好。 Bootstrap不是必需的,可以由任何其他庫或自己的樣式表代替。同樣適用於作為引導依賴性的jQuery 。這些庫中的任何一個都可以安全刪除,因為它們不影響htmx或_hyperscript 。
Web應用程序以標準請求響應方式與服務器通信。但是,與其他許多Web應用程序不同,沒有使用JSON。相反,服務器僅發送客戶端用來更新應用程序當前狀態的HTML代碼。
服務器程序接受兩個用於設置IP和端口的參數。
Usage: demo_web_server [options]
Optional arguments:
-h --help shows help message and exits [default: false]
-v --version prints version information and exits [default: false]
-i --ip-address Server IP Address [default: " 127.0.0.1 " ]
-p --port Port [default: 3000]
您還可以使用隨附的Drogon的config.json來控制服務器的行為。由於Drogon提供了很多選擇,因此您應該首先讓自己熟悉它。該項目中的配置文件僅包含一些設置。
還有一個基於JSON的配置文件server_config.json ,該文件將由Web服務器使用。目前,它僅定義SQLite3文件的位置,但將來會擴展。
{
"database" : {
"type" : " sqlite3 " ,
"file" : " demo.db "
}
}該文件不應與名為config.json的Drogon自己的JSON混淆。
麻省理工學院