
이 저장소에는 HTMX (Frontend) 및 Drogon C ++ 프레임 워크 (백엔드)를 기반으로 한 HDA가 포함되어 있습니다.
목표는 일반적인 JavaScript 프레임 워크를 사용하지 않고 반응 형 "웹 앱"을 만드는 것이 었습니다.
이 프로젝트에 대한 아이디어는 훌륭한 Book Hypermedia Systems를 읽는 동안 이루어졌습니다. 그것에서 저자는 modern 웹 응용 프로그램을 작성하는 대체 방법에 대해 이야기합니다. 웹 개발에 관한 다른 대부분의 책과 달리 저자는 JavaScript 프레임 워크에 의존하지 않고 대신 the web 자체 인 하이퍼 미디어 아키텍처의 뿌리로 돌아갑니다.
또한이 프로젝트에 관한 기사와 HTMX 및 C ++를 사용하려는 일반 동기를 썼습니다.
JavaScript를 사용하여 HTML을 극복하는 대신 기본적으로 90 년의 두꺼운 인류를 재현하는 전략 인 저자는 htmx 사용하여이를 보강합니다 . 그들은 영리한 자바 스크립트 트릭으로 돌아 가지 않고 더 많은 일을 할 수있게합니다. 물론 JS는 금지되지 않으며 htmx 자체는 자체 개발에 의존하지만 실제로는 필요하지 않기 때문에 JS는 보이지 않습니다.
HTMX가 확장하기 위해 여기에 있기 때문에 "불충분 한"하이퍼 미디어 컨트롤을 대체하기 위해 JS를 사용할 필요가 없습니다. 그것은 원래 정의 된대로 더 많은 일을 할 수있게합니다. 예를 들어, 앵커 태그 ( <a> )는 "업그레이드"하여 게시물, PIT, 패치 또는 요청을 삭제할 수 있도록 "업그레이드"할 수 있습니다. <form> 태그는 사후 요청을 통해 데이터를 전송하기위한 유일한 하이퍼 미디어 제어 일 필요는 없습니다. 정확히 똑같이 할 수있는 자신의 컨트롤을 작성하는 것은 어떻습니까? 아니면 서버의 기존 항목을 패치 할 수있는 <form> s? 일반적으로 명시 적 JS 코드를 요구하는 것은 이제 업그레이드 된 하이퍼 미디어 컨트롤을 사용하여 선언적으로 수행 할 수 있습니다.
이 프로젝트의 예는 다음과 같습니다. 거의 모든 충분한 복잡한 웹 앱에서 찾을 수있는 두 개의 버튼 ( 취소 및 저장 ).
< 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 라인이 필요하지 않았습니다. 이것이 하이퍼 미디어 아키텍처가 실제로 얼마나 강력한 지입니다.
또한 이벤트 처리를위한 작은 라이브러리 인 _hyperscript 및 DOM 조작도 사용합니다. 그것으로, 우리는 HTML을 떠나지 않고 이벤트를 듣고 파견하고 DOM 객체를 조작 할 수 있습니다.
이 프로젝트의 예는 다음과 같습니다.
< 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 남아 있습니다.

Jsons를 앞뒤로 보내는 대신 ( 일부 내부 논리에 따라 파싱 할 때마다 ) HTML을 원래 설계된대로 사용할 수 있습니다. HTTP 프로토콜은 HTML로 인해 존재하지만 요즘 우리는 주로 JSON을 전송합니다. JSON은 애플리케이션 시맨틱 을 전송할 수 없기 때문에 실제로는 의미가 없습니다. 우리의 서버는 대부분 JSON API를 가진 데이터 제공 업체이기 때문에 Frontends에 대규모 JS 프레임 워크가 필요한 것은 당연합니다. 그리고 JSON API는 "편안한"것이 아닙니다.
이 책의 예제 백엔드 소스 코드는 Python으로 작성되었으며 C ++ 대신 사용할 수 있습니다. 사실, 나는 원래 Python API를 모방하려고 노력했기 때문에 둘 다 이해하는 데 큰 차이가 없어야합니다. 각 장을 읽는 동안 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 또는 다른 항목을 사용하지 마십시오!
새로 열린 배쉬 창 에서이 명령을 입력하여 필요한 패키지를 설치하십시오.
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 .$HOME/.bash_profile 으로 .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 기본 Visual C ++ 컴파일러 대신 MingW를 사용하도록 지시해야합니다. 또한 정적 라이브러리 만 컴파일하기를 원하기 때문에 static 접미사를 사용하여 발표합니다.
다른 패키지와 달리 Drogon은 vcpkg 와 함께 설치되지 않습니다. 현재 사용 가능한 VCPKG 패키지는 컴파일 오류가 발생하므로 수동으로 컴파일 해야하는 이유입니다.
드로곤 소스를 복제하고 빌드 환경을 준비하십시오. 아래 예제의 /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을 컴파일하고 완료 될 때까지 기다리십시오.
마지막으로 Drogon을 설치하여 make install .
이제 C:/bin/drogon 의 폴더 목록이 표시됩니다.

두 번째 단계는 정적으로 연결될 몇 개의 라이브러리를 설치하는 것입니다. 우리는 vcpkg 사용하여 모두 컴파일합니다.
동일한 배쉬 창에서 다음 명령을 발행하여 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 저장소를 가리 킵니다.

Makefiles 유지하기가 어렵고 CMake 사용하는 방법을 배우고 싶지 않기 때문에 선택한 제작 시스템은 메손입니다. 사용자 퇴치 소프트웨어의 경우 수명이 너무 짧습니다.
buildall.sh (macos/linux)와 buildall.ps1 (Windows)의 두 가지 스크립트가 있습니다. 이 두 단계를 사용하면 다음 단계가 실행됩니다.
builddir ( Windows, MacOS/Linux에서만 Meson에 의해 수행됩니다 ) 복사하십시오.drogon_ctl 사용하여 CSPS를 C ++ 소스 파일로 변환하고 src/views 에 넣습니다.src 에서 소스를 컴파일합니다builddir 에 넣으십시오C ++ 20 컴파일러가 필요합니다. GNU C ++ v12.1.0을 사용하고 있습니다.
프로젝트를 구축하기 전에 meson.build 파일 에이 두 가지 변수를 조정하십시오.
triplet 은 호스트 머신 (예 : x64-osx 에 대한 정보를 가지고 있습니다.
vcpkg_root 는 vcpkg 에서 설치 한 패키지를 포함하는 루트 폴더입니다.
drogon_ctl Meson 에서 CSP 템플릿을 C ++ 파일로 변환하는 데 사용됩니다.

프론트 엔드는 스타일링을 위해 HTMX 라이브러리와 일부 Bootstrap 리소스를 사용합니다. HTMX가 이미 modern 웹 앱을 제공 할 것으로 예상 responsive 형 자료를 제공하므로 손으로 작성된 JavaScript가 실행되지 않습니다.
백엔드는 Drogon 이라는 매우 빠른 C ++ 웹 프레임 워크를 기반으로합니다.
사용중인 데이터베이스는 SQLITE3이지만 다른 SQL 데이터베이스로 쉽게 교체 할 수 있습니다. src/database/db_mgr.cpp 클래스를 조정하기 만하면됩니다. SQLITE3에 액세스하기위한 라이브러리는 SOCI이며 다른 많은 데이터베이스 백엔드를 지원합니다. 이 프로젝트의 루트에는 앱이 기본적으로 사용하는 sqlite3 파일 demo.db 포함되어 있습니다. 사용 가능한 CSV 파일 인 contacts.csv 도 새 테이블을 채우는 데 사용할 수있는 몇 가지 항목이 포함되어 있습니다.

controllers 에는 Drogon이 사용하는 클래스가 포함되어 있으며 클라이언트 호출을 백엔드에서 함수에 매핑합니다.database 에는 sqlite3 인스턴스에 액세스하기위한 작은 래퍼 클래스가 포함되어 있습니다.dtos 에는 프론트 엔드와 백엔드 사이의 데이터 탠 스퍼에 사용되는 Data Transfer Objects 포함되어 있습니다.templates 에는 CSP (C ++ 서버 페이지)가 포함되어 있으며 drogon_ctl C ++ 소스를 생성하는 데 사용하는 템플릿입니다. 이 소스는 HTML 출력을 만드는 데 사용됩니다.views 에는 드로곤이 생성 된 C ++ 클래스가 포함되어 있습니다. 이 파일은 수동으로 편집해서는 안됩니다 . 그들은 모든 빌드에서 교체됩니다. 동작이나 내용을 변경하려면 templates 폴더의 CSP를 대신 사용하십시오. 테스트는 Criterion 라이브러리로 수행됩니다.
기준은 brew install criterion 통해 설치할 수 있습니다. 그렇지 않으면 여기에 설명 된대로 수동으로 빌드 할 수 있습니다.
Meson 과의 기준을 구축하려면 먼저 repo를 복제하십시오.
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 웹 응용 프로그램은 id = "main" 인 div 태그가 포함 된 index.html 로드하여 시작합니다. 앱 전체 에서이 태그는 다른 컨트롤에서 사용하여 페이지 새로 고침없이 내용을 동적으로 교체하는 데 사용됩니다. 그러나 다른 전형적인 modern 웹 앱과 달리 반응 또는 Angular와 같은 JS 프레임 워크를 사용하여 앱을 반응하게 만듭니다. 대신, 우리는 htmx 스크립팅 라이브러리로만 사용합니다.
3 개의 bootstrap 리소스가 포함되어 있지만 이는 앱을 개선하는 것입니다. 부트 스트랩은 요구 사항이 아니며 다른 라이브러리 또는 자체 스타일로 교체 할 수 있습니다. 부트 스트랩 의존성으로 포함 된 jQuery 에도 동일하게 적용됩니다. 해당 라이브러리는 htmx 또는 _hyperscript 영향을 미치지 않으므로 안전하게 제거 할 수 있습니다.
웹 앱은 표준 요청-응답 방식으로 서버와 통신합니다. 그러나 다른 많은 웹 앱과 달리 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 도 있습니다. 현재 SQLITE3 파일의 위치 만 정의하지만 향후 확장 될 것입니다.
{
"database" : {
"type" : " sqlite3 " ,
"file" : " demo.db "
}
} 이 파일은 config.json 이라는 Drogon의 JSON과 혼동해서는 안됩니다.
MIT