Project

General

Profile

Passing a user-defined parameter to a web server entry point without using global variables.

Added by George McFie over 2 years ago

I would like to pass a custom (user-defined) variable to my web site entry point without having to use global variables.
For example, my entry code looks something like the following ...

namespace
{
const Setup* globalSetup = nullptr;     // <<<<<<<<<<<<< Ugly global variable
}

std::unique_ptr<Wt::WApplication> CreateApplication (const Wt::WEnvironment& environment)
{
    auto application = Wt::cpp14::make_unique<Wt::WApplication> (environment);

    ...

    application->root()->addWidget (Wt::cpp14::make_unique<Roster> (application.get(), environment, *globalSetup));    // <<<<<<<< Global used here

    return application;
}

class WebServer : public Wt::WServer
{
public:
    WebServer (const Setup& setup, int argc, char* argv[]);
    virtual ~WebServer() override = default;
    ...
};

WebServer::WebServer (const Setup& setup, int argc, char* argv[])
    : Wt::WServer (argc, argv, WTHTTP_CONFIGURATION)
{
    globalSetup = &setup;

    Wt::WServer::addEntryPoint (Wt::EntryPointType::Application, CreateApplication);
}

Is there a clean way to do this without using the intermediate 'globalSetup' global?


Replies (3)

RE: Passing a user-defined parameter to a web server entry point without using global variables. - Added by Stefan Bn over 2 years ago

I would say this is rather a general C++ software architecture question than a Wt question.

Depending on what your app does, usually you will have some kind of data persistence layer/mechanism to handle configuration data or data that the app user generates, such as a SQL database, INI files or just hard coded data storage in your code.

You could check the Blog example in wt/examples/blog to see how data persistence is done using good practice 'Model-View-Controller' pattern between Wt classes.

Regarding your const Setup* globalSetup = nullptr;: with Wt I felt in love with the Json::Object data representation, since it's easy to create/read, pass around and persist to database/any file.

RE: Passing a user-defined parameter to a web server entry point without using global variables. - Added by Rathnadhar K V over 2 years ago

Namaskara,

Its very easy to do it....

Here is how i did it...

-----------------------------------------------------------------------------------------------------------------Header file

class web_application : public Wt::WApplication
{
    private:
            CONST_SESSION_UNIQUE_HANDLE_REF                 web_session_unique_handle_ref;
    public:
            web_application(const Wt::WEnvironment&         env,
                            CONST_SESSION_UNIQUE_HANDLE_REF session_unique_handle_ref
                           );
    };
}

----------------------------------------------------------------------------------------------------------------src file

web_application::web_application(const Wt::WEnvironment&            env,
                                 CONST_SESSION_UNIQUE_HANDLE_REF    session_unique_handle_ref
                                 )
        : Wt::WApplication{env},
          web_session_unique_handle_ref{session_unique_handle_ref}
    {
        ..... Your code here....
    }

int main(int argc, char **argv)
{
    try
    {

        LOG(INFO) << fmt::format(
                                  "\n┌{0:─^{2}}┐\n"
                                    "│{1: ^{2}}│\n"
                                    "└{0:─^{2}}┘\n",
                                    "",
                                    "Wt Web Server",
                                    39
                                );

        Wt::WServer server{argc, argv, WTHTTP_CONFIGURATION};

        //ctor of session has configuration logic too.....
        auto session_unique_handle = std::make_unique<Session>("session.db"); //creating and connecting to the database

        server.addEntryPoint(Wt::EntryPointType::Application,
                             [&](const Wt::WEnvironment& env)
                                 {
                                     return std::make_unique<web_application>(env,
                                                                              session_unique_handle
                                                                             );
                                 },
                                 NULL_STRING,
                                 "resources/icons/favicon.ico"
                            );

        //Get set and GO!!!
        server.run();
    }
    catch(exception& dex)
    {
        LOG(ERROR) << dex.what();
        exit(1);
    }

    exit(0);
}


Hope it helps...

RE: Passing a user-defined parameter to a web server entry point without using global variables. - Added by George McFie over 2 years ago

Ah, yes of course! I don't know why I didn't think to use a lambda.
Thanks Namaskara - nice solution.

    (1-3/3)