main.cpp Example FileΒΆ

<@comment>// Copyright (C) 2022 The Qt Company Ltd.</@comment>
<@comment>// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause</@comment>

<@preprocessor>#include &quot;apibehavior.h&quot;</@preprocessor>
<@preprocessor>#include &quot;types.h&quot;</@preprocessor>
<@preprocessor>#include &quot;utils.h&quot;</@preprocessor>
<@preprocessor>#include &lt;QtCore/QCoreApplication&gt;</@preprocessor>
<@preprocessor>#include &lt;QtHttpServer/QHttpServer&gt;</@preprocessor>

<@preprocessor>#define SCHEME &quot;http&quot;</@preprocessor>
<@preprocessor>#define HOST &quot;127.0.0.1&quot;</@preprocessor>
<@preprocessor>#define PORT 49425</@preprocessor>

<@keyword>template</@keyword><@op>&lt;</@op><@keyword>typename</@keyword> T<@op>&gt;</@op>
<@type>void</@type> addCrudRoutes(<@type>QHttpServer</@type> <@op>&amp;</@op>httpServer<@op>,</@op> <@keyword>const</@keyword> <@type>QString</@type> <@op>&amp;</@op>apiPath<@op>,</@op> CrudApi<@op>&lt;</@op>T<@op>&gt;</@op> <@op>&amp;</@op>api<@op>,</@op>
                   <@keyword>const</@keyword> SessionApi <@op>&amp;</@op>sessionApi)
{
    httpServer<@op>.</@op>route(
            <@type>QString</@type>(<@string>&quot;%1&quot;</@string>)<@op>.</@op>arg(apiPath)<@op>,</@op> <@type>QHttpServerRequest</@type><@op>::</@op>Method<@op>::</@op>Get<@op>,</@op>
            <@op>[</@op><@op>&amp;</@op>api<@op>]</@op>(<@keyword>const</@keyword> <@type>QHttpServerRequest</@type> <@op>&amp;</@op>request) { <@keyword>return</@keyword> api<@op>.</@op>getPaginatedList(request); });

    httpServer<@op>.</@op>route(<@type>QString</@type>(<@string>&quot;%1/&lt;arg&gt;&quot;</@string>)<@op>.</@op>arg(apiPath)<@op>,</@op> <@type>QHttpServerRequest</@type><@op>::</@op>Method<@op>::</@op>Get<@op>,</@op>
                     <@op>[</@op><@op>&amp;</@op>api<@op>]</@op>(<@type>qint64</@type> itemId) { <@keyword>return</@keyword> api<@op>.</@op>getItem(itemId); });

    httpServer<@op>.</@op>route(<@type>QString</@type>(<@string>&quot;%1&quot;</@string>)<@op>.</@op>arg(apiPath)<@op>,</@op> <@type>QHttpServerRequest</@type><@op>::</@op>Method<@op>::</@op>Post<@op>,</@op>
                     <@op>[</@op><@op>&amp;</@op>api<@op>,</@op> <@op>&amp;</@op>sessionApi<@op>]</@op>(<@keyword>const</@keyword> <@type>QHttpServerRequest</@type> <@op>&amp;</@op>request) {
                         <@keyword>if</@keyword> (<@op>!</@op>sessionApi<@op>.</@op>authorize(request)) {
                             <@keyword>return</@keyword> <@type>QHttpServerResponse</@type>(
                                     <@type>QHttpServerResponder</@type><@op>::</@op>StatusCode<@op>::</@op>Unauthorized);
                         }
                         <@keyword>return</@keyword> api<@op>.</@op>postItem(request);
                     });

    httpServer<@op>.</@op>route(<@type>QString</@type>(<@string>&quot;%1/&lt;arg&gt;&quot;</@string>)<@op>.</@op>arg(apiPath)<@op>,</@op> <@type>QHttpServerRequest</@type><@op>::</@op>Method<@op>::</@op>Put<@op>,</@op>
                     <@op>[</@op><@op>&amp;</@op>api<@op>,</@op> <@op>&amp;</@op>sessionApi<@op>]</@op>(<@type>qint64</@type> itemId<@op>,</@op> <@keyword>const</@keyword> <@type>QHttpServerRequest</@type> <@op>&amp;</@op>request) {
                         <@keyword>if</@keyword> (<@op>!</@op>sessionApi<@op>.</@op>authorize(request)) {
                             <@keyword>return</@keyword> <@type>QHttpServerResponse</@type>(
                                     <@type>QHttpServerResponder</@type><@op>::</@op>StatusCode<@op>::</@op>Unauthorized);
                         }
                         <@keyword>return</@keyword> api<@op>.</@op>updateItem(itemId<@op>,</@op> request);
                     });

    httpServer<@op>.</@op>route(<@type>QString</@type>(<@string>&quot;%1/&lt;arg&gt;&quot;</@string>)<@op>.</@op>arg(apiPath)<@op>,</@op> <@type>QHttpServerRequest</@type><@op>::</@op>Method<@op>::</@op>Patch<@op>,</@op>
                     <@op>[</@op><@op>&amp;</@op>api<@op>,</@op> <@op>&amp;</@op>sessionApi<@op>]</@op>(<@type>qint64</@type> itemId<@op>,</@op> <@keyword>const</@keyword> <@type>QHttpServerRequest</@type> <@op>&amp;</@op>request) {
                         <@keyword>if</@keyword> (<@op>!</@op>sessionApi<@op>.</@op>authorize(request)) {
                             <@keyword>return</@keyword> <@type>QHttpServerResponse</@type>(
                                     <@type>QHttpServerResponder</@type><@op>::</@op>StatusCode<@op>::</@op>Unauthorized);
                         }
                         <@keyword>return</@keyword> api<@op>.</@op>updateItemFields(itemId<@op>,</@op> request);
                     });

    httpServer<@op>.</@op>route(<@type>QString</@type>(<@string>&quot;%1/&lt;arg&gt;&quot;</@string>)<@op>.</@op>arg(apiPath)<@op>,</@op> <@type>QHttpServerRequest</@type><@op>::</@op>Method<@op>::</@op>Delete<@op>,</@op>
                     <@op>[</@op><@op>&amp;</@op>api<@op>,</@op> <@op>&amp;</@op>sessionApi<@op>]</@op>(<@type>qint64</@type> itemId<@op>,</@op> <@keyword>const</@keyword> <@type>QHttpServerRequest</@type> <@op>&amp;</@op>request) {
                         <@keyword>if</@keyword> (<@op>!</@op>sessionApi<@op>.</@op>authorize(request)) {
                             <@keyword>return</@keyword> <@type>QHttpServerResponse</@type>(
                                     <@type>QHttpServerResponder</@type><@op>::</@op>StatusCode<@op>::</@op>Unauthorized);
                         }
                         <@keyword>return</@keyword> api<@op>.</@op>deleteItem(itemId);
                     });
}

<@type>int</@type> main(<@type>int</@type> argc<@op>,</@op> <@type>char</@type> <@op>*</@op>argv<@op>[</@op><@op>]</@op>)
{
    <@type>QCoreApplication</@type> app(argc<@op>,</@op> argv);

    <@type>QCommandLineParser</@type> parser;
    parser<@op>.</@op>addOptions({
            { <@string>&quot;port&quot;</@string><@op>,</@op> <@type>QCoreApplication</@type><@op>::</@op>translate(<@string>&quot;main&quot;</@string><@op>,</@op> <@string>&quot;The port the server listens on.&quot;</@string>)<@op>,</@op>
              <@string>&quot;port&quot;</@string> }<@op>,</@op>
    });
    parser<@op>.</@op>addHelpOption();
    parser<@op>.</@op>process(app);

    <@type>quint16</@type> portArg <@op>=</@op> PORT;
    <@keyword>if</@keyword> (<@op>!</@op>parser<@op>.</@op>value(<@string>&quot;port&quot;</@string>)<@op>.</@op>isEmpty())
        portArg <@op>=</@op> parser<@op>.</@op>value(<@string>&quot;port&quot;</@string>)<@op>.</@op>toUShort();

    <@keyword>auto</@keyword> colorFactory <@op>=</@op> std<@op>::</@op>make_unique<@op>&lt;</@op>ColorFactory<@op>&gt;</@op>();
    <@keyword>auto</@keyword> colors <@op>=</@op> tryLoadFromFile<@op>&lt;</@op>Color<@op>&gt;</@op>(<@op>*</@op>colorFactory<@op>,</@op> <@string>&quot;:/assets/colors.json&quot;</@string>);
    CrudApi<@op>&lt;</@op>Color<@op>&gt;</@op> colorsApi(std<@op>::</@op>move(colors)<@op>,</@op> std<@op>::</@op>move(colorFactory));

    <@keyword>auto</@keyword> userFactory <@op>=</@op> std<@op>::</@op>make_unique<@op>&lt;</@op>UserFactory<@op>&gt;</@op>(SCHEME<@op>,</@op> HOST<@op>,</@op> portArg);
    <@keyword>auto</@keyword> users <@op>=</@op> tryLoadFromFile<@op>&lt;</@op>User<@op>&gt;</@op>(<@op>*</@op>userFactory<@op>,</@op> <@string>&quot;:/assets/users.json&quot;</@string>);
    CrudApi<@op>&lt;</@op>User<@op>&gt;</@op> usersApi(std<@op>::</@op>move(users)<@op>,</@op> std<@op>::</@op>move(userFactory));

    <@keyword>auto</@keyword> sessionEntryFactory <@op>=</@op> std<@op>::</@op>make_unique<@op>&lt;</@op>SessionEntryFactory<@op>&gt;</@op>();
    <@keyword>auto</@keyword> sessions <@op>=</@op> tryLoadFromFile<@op>&lt;</@op>SessionEntry<@op>&gt;</@op>(<@op>*</@op>sessionEntryFactory<@op>,</@op> <@string>&quot;:/assets/sessions.json&quot;</@string>);
    SessionApi sessionApi(std<@op>::</@op>move(sessions)<@op>,</@op> std<@op>::</@op>move(sessionEntryFactory));

    <@comment>// Setup QHttpServer</@comment>
    <@type>QHttpServer</@type> httpServer;
    httpServer<@op>.</@op>route(<@string>&quot;/&quot;</@string><@op>,</@op> <@op>[</@op><@op>]</@op>() {
        <@keyword>return</@keyword> <@string>&quot;Qt Colorpalette example server. Please see documentation for API description&quot;</@string>;
    });

    addCrudRoutes(httpServer<@op>,</@op> <@string>&quot;/api/unknown&quot;</@string><@op>,</@op> colorsApi<@op>,</@op> sessionApi);
    addCrudRoutes(httpServer<@op>,</@op> <@string>&quot;/api/users&quot;</@string><@op>,</@op> usersApi<@op>,</@op> sessionApi);

    <@comment>// Login resource</@comment>
    httpServer<@op>.</@op>route(
            <@string>&quot;/api/login&quot;</@string><@op>,</@op> <@type>QHttpServerRequest</@type><@op>::</@op>Method<@op>::</@op>Post<@op>,</@op>
            <@op>[</@op><@op>&amp;</@op>sessionApi<@op>]</@op>(<@keyword>const</@keyword> <@type>QHttpServerRequest</@type> <@op>&amp;</@op>request) { <@keyword>return</@keyword> sessionApi<@op>.</@op>login(request); });

    httpServer<@op>.</@op>route(<@string>&quot;/api/register&quot;</@string><@op>,</@op> <@type>QHttpServerRequest</@type><@op>::</@op>Method<@op>::</@op>Post<@op>,</@op>
                     <@op>[</@op><@op>&amp;</@op>sessionApi<@op>]</@op>(<@keyword>const</@keyword> <@type>QHttpServerRequest</@type> <@op>&amp;</@op>request) {
                         <@keyword>return</@keyword> sessionApi<@op>.</@op>registerSession(request);
                     });

    httpServer<@op>.</@op>route(<@string>&quot;/api/logout&quot;</@string><@op>,</@op> <@type>QHttpServerRequest</@type><@op>::</@op>Method<@op>::</@op>Post<@op>,</@op>
                     <@op>[</@op><@op>&amp;</@op>sessionApi<@op>]</@op>(<@keyword>const</@keyword> <@type>QHttpServerRequest</@type> <@op>&amp;</@op>request) {
                         <@keyword>return</@keyword> sessionApi<@op>.</@op>logout(request);
                     });

    <@comment>// Images resource</@comment>
    httpServer<@op>.</@op>route(<@string>&quot;/img/faces/&lt;arg&gt;-image.jpg&quot;</@string><@op>,</@op> <@type>QHttpServerRequest</@type><@op>::</@op>Method<@op>::</@op>Get<@op>,</@op>
                     <@op>[</@op><@op>]</@op>(<@type>qint64</@type> imageId<@op>,</@op> <@keyword>const</@keyword> <@type>QHttpServerRequest</@type> <@op>&amp;</@op>) {
                         <@keyword>return</@keyword> <@type>QHttpServerResponse</@type><@op>::</@op>fromFile(
                                 <@type>QString</@type>(<@string>&quot;:/assets/img/%1-image.jpg&quot;</@string>)<@op>.</@op>arg(imageId));
                     });

    <@keyword>auto</@keyword> tcpserver <@op>=</@op> std<@op>::</@op>make_unique<@op>&lt;</@op><@type>QTcpServer</@type><@op>&gt;</@op>();
    <@keyword>if</@keyword> (<@op>!</@op>tcpserver<@op>-</@op><@op>&gt;</@op>listen(<@type>QHostAddress</@type><@op>::</@op>Any<@op>,</@op> portArg) <@op>|</@op><@op>|</@op> <@op>!</@op>httpServer<@op>.</@op>bind(tcpserver<@op>.</@op>get())) {
        <@func target="qDebug()">qDebug</@func>() <@op>&lt;</@op><@op>&lt;</@op> <@type>QCoreApplication</@type><@op>::</@op>translate(<@string>&quot;QHttpServerExample&quot;</@string><@op>,</@op>
                                                <@string>&quot;Server failed to listen on a port.&quot;</@string>);
        <@keyword>return</@keyword> <@number>0</@number>;
    }
    <@type>quint16</@type> port <@op>=</@op> tcpserver<@op>-</@op><@op>&gt;</@op>serverPort();
    tcpserver<@op>.</@op>release();

    <@func target="qDebug()">qDebug</@func>() <@op>&lt;</@op><@op>&lt;</@op> <@type>QCoreApplication</@type><@op>::</@op>translate(
                        <@string>&quot;QHttpServerExample&quot;</@string><@op>,</@op>
                        <@string>&quot;Running on http://127.0.0.1:%1/ (Press CTRL+C to quit)&quot;</@string>)
                        <@op>.</@op>arg(port);

    <@keyword>return</@keyword> app<@op>.</@op>exec();
}