drogonframework / drogon

Drogon: A C++14/17/20 based HTTP web application framework running on Linux/macOS/Unix/Windows
MIT License
11.57k stars 1.12k forks source link

Manual vs Automatic registration of controllers #1787

Closed drizzle042 closed 5 months ago

drizzle042 commented 1 year ago

The automated mechanism of Drogon’s registration of controllers is fantastic. Users don’t have to register controllers manually via the drogon::HttpAppFramework::registerController(const std::shared_ptr&) method keeping the interface clean.

Now here comes the issue I’m facing and so far I have looked all over for what I might be doing wrong. I haven’t seen anyone else facing the same issue. Sometimes I might do certain things in my app and I’ll end up missing the automated controller registration train —my controllers end up not getting registered. I don’t know what I usually do wrong to end up this way. Other times I don’t and my controllers are properly registered. Recently I have had to go with the manual process which is a pain.

My application is built as a static library in mind. The singleton instance of my application has an App::run() method which runs drogon::HttpAppFramework::run() under the hood. This application will be linked to an executable somewhere which is of the structure

GUI
    Setup Server
    Make External Calls
    Generate Recovery Journal
    Run Server
CLI 
    Setup Server
    Make External Calls
    Generate Recovery Journal
    Run Server

Sorry for the repetition but the app as a CLI does everything the GUI can do.

Run Server

Is a call a client can make with a button on the GUI or via a command line argument on the CLI and it calls App::run() method of my static library which as I mentioned earlier calls drogon::run() method.

Automated registration of controllers does not register my controllers properly with this dev approach and I end up missing that train so I go with the manual route —it is a real pain. Can someone help me with this issue? Like I said I’m not sure this is the main reason for that because I couldn’t understand how Drogon automatically registers controllers even after I read the sources so please if there is someone who understands this better than I do, I will really appreciate the help. I tried to be as detailed as I could be.

an-tao commented 1 year ago

@drizzle042 Thanks for your feedback, I suspect this may be due to global variables not explicitly used in the static library not being linked to the final executable program. There is a compromise you can try. Include all controller header files in the main.cc file, then recompile and see if it works.

drizzle042 commented 1 year ago

Thanks @an-tao. Such prompt response, I’m really grateful. I have done this once mistakenly. I have included a controller once without manually adding it just yet to the drogon::HttpAppFramework via drogon::HttpAppFramework::registerController(const std::shared_ptr&) and it did get added either. The solution all this while has been drogon::HttpAppFramework::registerController(const std::shared_ptr&). Thanks again friend. You are the Author so I bet I’m in the best hands now 🤓.

drizzle042 commented 1 year ago

Hi @an-tao! I’m sorry if I misunderstood your suggestion earlier but I have something in mind I think you want me to try but I can’t do so unfortunately. The users of my static library are only exposed to my App.hpp file where App::run() is declared. In addition, they are given the static library so that they will link to it. The implementation details of what might be going on in the library is not divulged because they shouldn’t know it. One team is in charge of the GUI and another for the CLI you see. So I can’t mandate them to include the controllers directly in their code. All they use are the App.hpp file and the static library.

Did you have something else in mind you might want me to try? I’m grateful for the help so far.

GitJQ commented 1 year ago

@drizzle042 @an-tao I have tried to include controller header files in my static library implement file, and Automatic registration works。

main.cc

`

include "server/web_app.h"

int main() { WebService::run(); return 0; } `

server.zip

drizzle042 commented 1 year ago

Hi @GitJQ how well have you tested? Does it work every time? So you don’t need to manually register anymore? Just including into the file running the drogon::run() operation solved this. Hmm, seems improbable to me. I’ll try it then. I’ll just include the controller but I won’t manually register.

GitJQ commented 1 year ago

Hi @GitJQ how well have you tested? Does it work every time? So you don’t need to manually register anymore? Just including into the file running the drogon::run() operation solved this. Hmm, seems improbable to me. I’ll try it then. I’ll just include the controller but I won’t manually register.

Hi,I have tested HttpSimpleController、HttpController、WebSocketController,no any manually register. All controller works fine now.

  1. gcc version 11.1.0
  2. drogon 1.8.7

include <drogon/HttpAppFramework.h>

include "web_app.h"

// i just add header files here **#include "controllers/user.h"

include "controllers/simple.h"

include "controllers/echo_websock.h"**

void WebService::run() { drogon::app().loadConfigFile("config.json"); drogon::app().run(); }