【View編】最速のC++ Webフレームワーク「Drogon」を試してみた!
IT技術

View 編~最速のC++ Webフレームワーク「Drogon」を試してみた!~

最速の Web フレームワークとして注目を集めている「Drogon」。
前回は、コントローラについて紹介しました。
View を作ってみよう!
今回は、Web アプリケーションの中でも重要な「View」について解説していきます。
Web 上で視覚的に動作するアプリを作成する場合、データのやり取りはもちろん、ユーザビリティにも大きく関わる部分です。
Drogon では、ビューを動的に生成することが可能です。
ビューのコントローラの生成
まずは、ビューを表示させるために必要不可欠なコントローラを生成しましょう!
今回は、受け取った GET パラメータを展開するビューを作成したいので、「ListParaCtrl」と言う名前にします。
1$ drogon_ctl create controller ListParaCtrlヘッダーファイルでルーティング
それでは、ヘッダーファイルから見てみます。
1#pragma once
2#include <drogon/HttpSimpleController.h>
3using namespace drogon;
4class ListParaCtrl:public drogon::HttpSimpleController<ListParaCtrl>
5{
6  public:
7    virtual void asyncHandleHttpRequest(const HttpRequestPtr& req, std::function<void (const HttpResponsePtr &)> &&callback) override;
8    PATH_LIST_BEGIN
9
10    PATH_ADD("/listpara", Get);
11
12    PATH_LIST_END
13};「/listpara」という URL をルーティングします。
ソースファイル実装
ソースファイルは、以下のように実装します。
1#include "ListParaCtrl.h"
2void ListParaCtrl::asyncHandleHttpRequest(const HttpRequestPtr& req, std::function<void (const HttpResponsePtr &)> &&callback)
3{
4    // Viewに渡すデータを格納する
5    HttpViewData data;
6    data.insert("title", "list parameters");
7    data.insert("parameters", 
8            req->getParameters()  // Getパラメータはこのように取得
9            );
10    
11    // ListParaView.cspというビューにデータを渡す (詳細は後述)
12    auto res = drogon::HttpResponse::newHttpViewResponse("ListParaView.csp", data);
13    callback(res);
14}ここで、「GET パラメータの受け取り方」や「ビューへのデータの渡し方」を確認しておきましょう!
CSP(ビュー)の作成
さて、Drogon では、動的な HTML ページを生成するために「CSP」というエンジンを使用しています。
CSP (ビュー) とは?
CSP は「C++ Server Pages」と言って、サーバサイドで C++ライクな構文を処理し、HTMLを生成するものです。
Java における JSP の C++版ととらえればわかりやすいでしょう。
CSP の記法
最初に、CSP の記法について説明しておきます。
基本的には HTML で、あるスコープ内では C++を記述できるのが CSP の特徴です。
CSP の記法は様々あるのですが、今回は代表的なものだけご紹介します。
<%inc %>
<%inc %> 内では、#include が使用可能です。
(例: <%inc #include <iostream> %> )
<%C++ %>
<%c++ %> 内では、その他の C++コードが記述可能です。
(例: <%c++ std::string name = "Tanaka"; %> )
@@
@@ は、コントローラ側で渡したデータ変数を指します。
例えば、先ほどのソースファイルでいうと、data そのものを指します。
逆に CSP ファイル内では data という名前では呼び出せず、@@ のみ参照可能となります。
$$
$$ は標準出力として動作します。
std::cout のようなもので、<< と一緒に使用します。
なお、改行はされません。
[[ ]]
[[ ]] 内に書かれた文字列をキーとして、コントローラ側から対応するデータを取得し、表示させます。
(例: [[ title ]] )
{% %}
{% %} 内では、あらかじめ<%c++ %> などで宣言された変数を展開できます。
これは、<%c++ $$<<name; %> と同義です。
(例: {% name %} )
<%view %>
<%view %> 内ではサブビューとして、他の CSP ファイルを展開できます。
もしheader.csp が存在すれば、<%view header %> のように記述して展開できます。
これにより、ページの共通部分を1つにまとめることが可能です。
実際に作ってみよう!
今回は、試しに以下のようなファイルを「/views」ディレクトリに作成してみました。
名前は「ListParaView.csp」です。
1<!DOCTYPE html>
2<html>
3<%c++
4// dataからunorder_mapとしてパラメータを取得
5auto para = @@.get<std::unordered_map<std::string, std::string>>("parameters");
6
7// 適当に変数宣言してみる
8auto name = "RightCode Inc.";
9auto date = "2020.08.01";
10%>
11<head>
12    <meta charset="UTF-8">
13    <title>[[ title ]]</title>
14</head>
15<body>
16
17<!-- 変数展開はどちらでも良い -->
18<p>Hello, {% name %}</p>
19<p>Date: <%c++ $$ << date; %></p>
20
21<%c++ if(para.size()>0){%>
22<H1>Parameters</H1>
23<table border="1">
24    <tr>
25        <th>name</th>
26        <th>value</th>
27    </tr>
28    <!-- イテレーションループでパラメータを展開 -->
29    <%c++ for(auto iter:para){ %>
30    <tr>
31        <td>{% iter.first %}</td> 
32        <td><%c++ $$<<iter.second;%></td>
33    </tr>
34    <%c++ } // endfor%>
35</table>
36<%c++ }else{ %>
37<H1>no parameter</H1>
38<%c++ } // endif %>
39</body>
40</html>動作確認
試しに、 http://localhost/listpara?arg1=tanaka&arg2=suzuki にアクセスしてみると、

上手く動作しているようです!
エラーが出る場合
もし、ビルドでエラーが出る場合は、CMakeLists.txt に以下を追記しましょう。
ただし、drogon_ctl コマンドでプロジェクトを生成しているなら、基本的には自動生成されるはずです。
1file(GLOB_RECURSE SCP_LIST ${CMAKE_CURRENT_SOURCE_DIR}/views/*.csp)
2foreach(cspFile ${SCP_LIST})
3    message(STATUS "cspFile:" ${cspFile})
4    get_filename_component(classname ${cspFile} NAME_WE)
5    message(STATUS "view classname:" ${classname})
6    ADD_CUSTOM_COMMAND(OUTPUT ${classname}.h ${classname}.cc
7            COMMAND drogon_ctl
8            ARGS create view ${cspFile}
9            DEPENDS ${cspFile}
10            VERBATIM )
11    set(VIEWSRC ${VIEWSRC} ${classname}.cc)
12endforeach()ハッシュマップ
Drogon では、GET パラメータはstd::unordered_map<> で実装されています。
これはいわゆるハッシュマップで、計算量0(1)でデータを取得できます。
順序付けがされないデメリットはありますが、こんなところも Drogon が最速と言われる一因でしょう。
drogon_ctl コマンドで C++ソースファイルの生成が可能
Drogon には、C++ソースファイルを生成するコントローラを、view ディレクトリ下に自動出力してくれる機能があります。
1$ drogon_ctl create view ListParaView.csp万が一、CSP ファイルの実行ができないサーバで運用する場合などは役に立つはずです。
さいごに
これで一通り、Drogon の主要機能の紹介が終わりました。
Drogon は多くの機能が実装されたフルスタックなWebフレームワークであり、とてもユーザーフレンドリーな仕様になっていると思います。
まだまだ Drogon の可能性は未知数です。
Web エンジニアのみなさん、これを機に C++に触れてみてはいかがでしょうか?
関連記事はこちら
こちらの記事もオススメ!
ライトコードでは、エンジニアを積極採用中!
ライトコードでは、エンジニアを積極採用しています!社長と一杯しながらお話しする機会もご用意しております。そのほかカジュアル面談等もございますので、くわしくは採用情報をご確認ください。
採用情報へ
「好きを仕事にするエンジニア集団」の(株)ライトコードです! ライトコードは、福岡、東京、大阪、名古屋の4拠点で事業展開するIT企業です。 現在は、国内を代表する大手IT企業を取引先にもち、ITシステムの受託事業が中心。 いずれも直取引で、月間PV数1億を超えるWebサービスのシステム開発・運営、インフラの構築・運用に携わっています。 システム開発依頼・お見積もり大歓迎! また、現在「WEBエンジニア」「モバイルエンジニア」「営業」「WEBデザイナー」を積極採用中です! インターンや新卒採用も行っております。 以下よりご応募をお待ちしております! https://rightcode.co.jp/recruit









