
Este repositório contém um HDA baseado na estrutura HTMX (frontend) e Drogon C ++ (back -end).
O objetivo era criar um "aplicativo da web" responsivo sem usar nenhuma das estruturas JavaScript usuais.
A idéia para este projeto veio ao ler os excelentes sistemas de livros Hypermedia. Nele, os autores falam sobre maneiras alternativas para escrever aplicativos da Web modern . Ao contrário da maioria dos outros livros sobre desenvolvimento da Web, os autores não dependem de nenhuma estrutura JavaScript, mas voltam às raízes da arquitetura Hypermedia que é the web .
Também escrevi um artigo sobre este projeto e minha motivação geral para usar o HTMX e o C ++.
Em vez de usar o JavaScript para superar o HTML, uma estratégia que basicamente reproduz os clientes espessos dos 90es, os autores usam htmx para aumentá- lo. Eles tornam capaz de fazer mais sem voltar a truques inteligentes de JavaScript. Obviamente, o JS não é proibido e o próprio htmx depende dele para seu próprio desenvolvimento, mas o JS não é visível, pois não há necessidade real.
Não precisamos usar o JS para substituir os controles de hipermídia aparentemente "insuficiente", porque o HTMX está aqui para estendê -los. Isso os torna capazes de fazer mais conforme definido originalmente. Uma tag de âncora ( <a> ), por exemplo, pode ser "atualizada" para que possa executar postagens, put, remendo ou até excluir solicitações. Uma tag <form> não precisa ser o único controle hipermediário para enviar dados por meio de solicitações de postagem. Que tal escrever seus próprios controles que podem fazer exatamente o mesmo? Ou talvez <form> s que possa corrigir entradas existentes no servidor? O que geralmente exige o código JS explícito agora pode ser feito declarativamente com os controles hipermídicos atualizados .
Aqui está um exemplo deste projeto. Dois botões ( Cancelar e salvar ) que podem ser encontrados em quase todos os aplicativos da web suficientemente complexos.
< 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 >Acredite ou não, mas esses dois utilizam as seguintes funcionalidades:
<button> .E nenhuma linha única de JavaScript era necessária para fazê -lo funcionar. É assim que a arquitetura hipermídica poderosa realmente é.
Também usamos _hyperscript, uma pequena biblioteca para manipulação de eventos e manipulação de DOM. Com isso, podemos ouvir e despachar eventos, manipular objetos DOM, tudo sem sair do HTML.
Aqui está um exemplo deste projeto:
< 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 > No segundo controle, temos alguns bits de <button> que fazem o seguinte:
O resultado final é a remoção dos botões Edit e Delete . Somente o botão Back permanece.

Em vez de enviar o JSONS para frente e para trás ( e cada vez que os analisando de acordo com alguma lógica interna ), podemos usar o HTML como originalmente projetado: como um veículo para aplicações significativas de hipermídia. O protocolo HTTP existe por causa do HTML, mas hoje em dia transferimos principalmente o JSON sobre ele. Na verdade, isso faz pouco sentido, porque o JSON não pode transportar a semântica do aplicativo, que afeta efetivamente o significado original da arquietura do cliente-servidor da web. Não é de admirar que precisemos de estruturas JS maciças em nossos frontends, porque nossos servidores são principalmente apenas provedores de dados com APIs JSON. E as APIs JSON não são "repousantes".
O código -fonte de back -end do livro é escrito no Python e pode ser usado em vez de C ++. Na verdade, tentei imitar as APIs originais do Python, para que não haja grandes lacunas para entender os dois. Eu estava escrevendo o código C ++ enquanto lia os respectivos capítulos.
Mas, como htmx é muito agnóstico, não há problema em usar qualquer idioma, então eu usei C ++. Isso também é bom da perspectiva de aprendizado, pois me obriga a verificar tudo.
Penso que devemos remover o inchaço não apenas de nossos frontends [ coloque qualquer estrutura JS enorme aqui ], mas também de nossos back -end [ coloque qualquer estrutura de back -end enorme aqui ]. O software maciço consome enormes quantidades de tempo e energia. Tempo humano e energia, bem como ciclos de CPU e eletricidade.
Algumas bibliotecas C ++ são necessárias para que a compilação seja bem -sucedida. Este projeto usa o VCPKG como gerenciador de pacotes, mas você é livre para escolher qualquer outro.
Para instalar um pacote, basta chamar vcpkg install PACKAGE_NAME .
Os pacotes a seguir são necessários:
drogon
drogon[ctl]
fmt
argparse
brotli
zlib
openssl
sqlite3
soci[core]
soci[sqlite3]
A busca por eles é fácil: vcpkg search PACKAGE_NAME
sudo apt install uuid-dev libcriterion-dev
Os usuários do Windows terão que configurar o ambiente MSYS primeiro. Após a instalação, selecione a entrada MSYS2 MINGW64 no menu Iniciar o Windows. Não use o MSYS UCRT4 ou qualquer outra entrada!
Na janela Bash recém -aberta, insira este comando para instalar os pacotes necessários:
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
Verifique se o compilador está disponível com which g++ . Você deve ver uma mensagem como esta:
$ which g++
/mingw64/bin/g++ Você também precisará de um editor para atualizar os caminhos do ambiente, então instale o seu preferido, por exemplo, pacman -Sy nano ou pacman -Sy vim
Abra seu .bash_profile com nano .$HOME/.bash_profile e adicione essas três linhas ao final do arquivo:
PATH=/mingw64/bin: $PATH
export VCPKG_DEFAULT_TRIPLET=x64-mingw-static
export VCPKG_DEFAULT_HOST_TRIPLET=x64-mingw-static Salve e feche o arquivo. Recarregue -o com: source $HOME/.bash_profile ou . ~/.bash_profile
As duas entradas trigêmeas serão necessárias posteriormente para instruir vcpkg a usar o Mingw em vez do compilador Visual C ++ padrão. E como também queremos compilar bibliotecas estáticas, anunciamos isso usando o sufixo static .
Ao contrário de outros pacotes, o Drogon não será instalado com vcpkg . Os erros de compilação do pacote VCPKG atualmente disponíveis, que é a razão pela qual precisamos compilá -lo manualmente.
Clone as fontes de Drogon e prepare o ambiente de construção. O caminho /c/bin/drogon do exemplo abaixo deve ser adaptado às configurações locais. A raiz deste caminho ( /c/bin ) deve mapear para um caminho já existente no sistema Windows, por exemplo C:/bin ou qualquer outro caminho da sua escolha.
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 Agora compile Drogon com make -j e aguarde até que ele conclua.
Finalmente, instale o Drogon com make install .
Agora você deve ver uma lista de pastas em C:/bin/drogon .

A segunda etapa é a instalação de algumas bibliotecas que serão vinculadas estaticamente. Usaremos vcpkg para compilar todos eles.
Na mesma janela Bash, emita os seguintes comandos para configurar vcpkg .
cd $HOME
git clone https://github.com/microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.batPerceber:
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.
Na pasta vcpkg , emita os seguintes comandos para instalar as bibliotecas necessárias:
./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] Agora você pode compilar este projeto via Poweshell com ./buildall.ps1 .
Mas não se esqueça de alterar vcpkg_root em meson.build primeiro. Esse caminho deve apontar para o repositório vcpkg clonado anteriormente.

Meu sistema de compilação de escolha é Meson, porque são Makefiles de manter e eu simplesmente não quero aprender a usar CMake . A vida é muito curta para o software hostil do usuário.
Existem dois scripts, buildall.sh (macOS/linux) e buildall.ps1 (Windows). Com estes dois, as seguintes etapas serão executadas:
builddir ( apenas no Windows, no macOS/Linux, isso será feito por Meson )drogon_ctl para converter CSPs em arquivos de origem C ++ e coloque -os em src/viewssrcbuilddirÉ necessário um compilador C ++ 20. Estou usando GNU C ++ v12.1.0.
Antes de tentar construir o projeto, adapte essas duas variáveis no arquivo meson.build :
O triplet carrega as informações sobre a máquina host, por exemplo, x64-osx .
O vcpkg_root é a pasta raiz que contém pacotes instalados pelo vcpkg .
drogon_ctl será usado pelo Meson para converter modelos CSP em arquivos C ++.

O front -end usa a biblioteca HTMX e alguns recursos Bootstrap para estilo. Não há JavaScript escrito à mão em execução, pois o HTMX já fornece as coisas responsive que esperamos que qualquer aplicativo da web modern ofereça.
O back -end é baseado na estrutura da web C ++ muito rápida chamada Drogon .
O banco de dados em uso é SQLITE3, mas pode ser substituído facilmente por qualquer outro banco de dados SQL. Basta ajustar a classe src/database/db_mgr.cpp . A biblioteca para acessar o SQLite3 é o SOCI e suporta muitos outros back -ends de banco de dados. A raiz deste projeto contém um arquivo sqlite3, demo.db , que o aplicativo usa por padrão. Há também um arquivo CSV disponível, contacts.csv , que contém algumas entradas que podem ser usadas para preencher uma nova tabela.

controllers contêm classes que Drogon usa para mapear chamadas de clientes para funções no back -end.database contém uma pequena classe de wrapper para acessar a instância do SQLITE3.dtos contém Data Transfer Objects que são usados para atirar dados entre o front -end e o back -end.templates contém CSPs (Páginas do servidor C ++), que são modelos que drogon_ctl usa para gerar fontes C ++. Essas fontes serão usadas para criar saídas HTML.views contém classes C ++ geradas por Drogon. Esses arquivos não devem ser editados manualmente . Eles serão substituídos em todas as construções. Para alterar seu comportamento ou conteúdo, use CSPs da pasta templates . Os testes são feitos com a biblioteca de critérios.
O critério pode ser instalado via brew install criterion . Caso contrário, você pode construí -lo manualmente, conforme descrito aqui.
Para construir critério com Meson , clone seu repositório primeiro:
git clone --recursive https://github.com/Snaipe/Criterion.gitEm seguida, emita os seguintes comandos:
cd Criterion
meson - Dprefix = c: / bin / criterion build
ninja - C build installO prefixo do diretório de instalação pode ser alterado. Após a conclusão da instalação, defina o caminho para o arquivo DLL do Criterion. Esta DLL será usada por executáveis de teste com critério vinculado.

As fontes de teste deste projeto estão localizadas em test e estão sendo construídas automaticamente pela Meson . Para executar testes, você pode usar estas duas opções:
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.txtOu chamando diretamente o próprio executivo de teste:
PS > .builddir test_demo_web_server.exe
[ ==== ] Synthesis: Tested: 1 | Passing: 1 | Failing: 0 | Crashing: 0 O aplicativo da Web começa carregando o index.html , que contém uma tag div com id = "main" . Em todo o aplicativo, essa tag será usada por outros controles para substituir dinamicamente seu conteúdo sem atualização de página. No entanto, diferentemente de outros aplicativos web modern típicos, não usamos estruturas JS como React ou Angular para tornar o aplicativo responsivo. Em vez disso, usamos apenas htmx como nossa biblioteca de script.
Há também três recursos bootstrap envolvidos, mas isso é apenas fazer com que o aplicativo pareça melhor. O Bootstrap não é um requisito e pode ser substituído por qualquer outra biblioteca ou folhas de estilo próprias. O mesmo se aplica ao jQuery incluído como uma dependência de bootstrap. Qualquer uma dessas bibliotecas pode ser removida com segurança, pois não afeta htmx ou _hyperscript .
O aplicativo da web se comunica com o servidor de maneira padrão de solicitação-resposta. Mas, diferentemente de muitos outros aplicativos da Web por aí, nenhum JSON está sendo usado. Em vez disso, o servidor está enviando apenas peças de código HTML que o cliente usa para atualizar o estado atual do aplicativo.
O programa do servidor aceita dois parâmetros para definir o IP e a porta.
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]
Você também pode usar o Drogon's config.json incluído para controlar o comportamento do servidor. Como Drogon oferece muitas opções, você deve primeiro se familiarizar com isso. O arquivo de configuração neste projeto contém apenas algumas configurações.
Também existe um arquivo de configuração baseado em JSON separado, server_config.json , que será usado pelo servidor da Web. Atualmente, ele define apenas o local do arquivo SQLITE3, mas será expandido no futuro.
{
"database" : {
"type" : " sqlite3 " ,
"file" : " demo.db "
}
} Este arquivo não deve ser confundido com o próprio JSON de Drogon, que se chama config.json .
Mit