
该存储库包含基于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即可。
需要以下包装:
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混淆。
麻省理工学院