• トップ
  • ブログ一覧
  • 【View編】最速のC++ Webフレームワーク「Drogon」を試してみた!
  • 【View編】最速のC++ Webフレームワーク「Drogon」を試してみた!

    広告メディア事業部広告メディア事業部
    2020.09.15

    IT技術

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

    最速の Web フレームワークとして注目を集めている「Drogon」。

    前回は、コントローラについて紹介しました。

    featureImg2020.09.13【Controller編】最速のC++ Webフレームワーク「Drogon」を試してみた!Controller 編~最速のC++ Web フレームワーク「Drogon」を試してみる~最速の Web フレームワ...

    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 にアクセスしてみると、

    動的にHTMLが生成されている

    上手く動作しているようです!

    エラーが出る場合

    もし、ビルドでエラーが出る場合は、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++に触れてみてはいかがでしょうか?

    関連記事はこちら

    featureImg2020.09.11【環境構築編】最速のC++ Webフレームワーク「Drogon」を試してみた!Web フレームワーク「Drogon」とは?つい最近、TechEmpower が独自でベンチマークを計測したランキング...

    featureImg2020.09.13【Controller編】最速のC++ Webフレームワーク「Drogon」を試してみた!Controller 編~最速のC++ Web フレームワーク「Drogon」を試してみる~最速の Web フレームワ...

    こちらの記事もオススメ!

    featureImg2020.07.17ライトコード的「やってみた!」シリーズ「やってみた!」を集めました!(株)ライトコードが今まで作ってきた「やってみた!」記事を集めてみました!※作成日が新し...
    featureImg2020.07.27IT・コンピューターの歴史特集IT・コンピューターの歴史をまとめていきたいと思います!弊社ブログにある記事のみで構成しているため、まだ「未完成状態」...
    featureImg2020.08.04エンジニアの働き方 特集社員としての働き方社員としてのエンジニアの働き方とは?ライトコードのエンジニアはどんな働き方をしてるのか、まとめたいと...

    広告メディア事業部

    広告メディア事業部

    おすすめ記事

    GitHubActionsのランナーに触れてみた

    こやまん(エンジニア)

    こやまん(エンジニア)

    2024.03.28

    IT技術

    Azure Data FactoryでSlackへ通知をしてみる

    たかやん(エンジニア)

    たかやん(エンジニア)

    2024.03.28

    IT技術

    GCP Secret Managerを使ってみた

    たなゆー(エンジニア)

    たなゆー(エンジニア)

    2024.03.21

    IT技術

    Bitriseのパイプラインと環境変数

    加納(エンジニア)

    加納(エンジニア)

    2024.03.11

    IT技術