drogon icon indicating copy to clipboard operation
drogon copied to clipboard

Is it possible to somehow declare the protocol within the server and client? Is there such a mechanism in dragon?

Open Rofl113 opened this issue 2 years ago • 5 comments

Good afternoon. Sorry if I wrote in the wrong section.

I tried to use your project and create a server. My idea was to make several Services and link them through a mutual connection. I wanted to do all this through one project by changing the BUILD_TYPE key to assemble the necessary Service. To deploy the backend for each Service, I used drogon::HttpController and described all the requests. When I connect from another Service to this one, I use drogon::HttpClient, but I didn't find how to describe the requests in this case and wrote them manually. The question is this: is it possible to somehow describe all the requests of one Service so that they can be used in the implementation as for the server side (drogon::HttpController) so for the client part (drogon::HttpClient)? Thus, I planned not to get errors if, say, the server part is updated (requests are added) and I forget to update the client part.

p.s. sorry if something like this already exists, I recently started studying drogon and may have overlooked the necessary code.

Rofl113 avatar Mar 22 '22 07:03 Rofl113

Do you mean you want to create webserver with drogonframework while able to listen another service in the background?


Because I'm not sure with what you describe, seems/sounds complicated enough for me tho


Based on

...
To deploy the backend for each Service, I used drogon::HttpController and described all the requests. When I connect from another Service to this one,
...

does this example related to your case?


Basically you want set your drogon server to listen port 80 and 443 and open your firewall to public, then on this config and listen some running service/s

I haven't figure it out yet if the running background service is not on the same plugin, or how to separate 'em

Since this one is interesting if someone want to decide drogon as their webserver


Pardon if it's not related to your case.

prothegee avatar Mar 24 '22 13:03 prothegee

Can't really understand your question. Are you finding something like microservice and service registration?

hwc0919 avatar Mar 25 '22 04:03 hwc0919

I think the question is geared more towards some kind of mechanism in drogon_ctl that could generate templates for services. I’m also just guessing, but I understand the request as follows:

  1. There is some kind of description mechanism for services (our JSON configuration could be reused or a new one introduced)
  2. Server (“service”) templates / controllers are created based on the definition in the first bullet point
  3. Client templates are then created based on the server templates, and they are automatically prefilled with requests to these specific API endpoints

This is similar to what we currently have in the ORM by describing relationships, but this would obviously be on a completely different architectural layer.

This kind of functionality isn’t part of Drogon, and I think this also isn’t planned, but every contribution is welcome. I think this would be a great addition to the project.

Please correct me if I’m wrong @Rofl113.

rbugajewski avatar Mar 25 '22 12:03 rbugajewski

Sorry, I didn't describe the question well. I use a translator. I think @rbugajewski you have understood correctly. Let's say we have an openapi 3.0 yaml file and using the script and this file, we generate:

  1. All structures for Request.
  2. All structures for Response.
  3. Interface ClientApi class.
  4. Interface ServerApi class (It will probably be the same).
  5. Implementation of ClientApi using Drogon - ClientApiDrogon.
  6. Implementation of ServerApi using Drogon - ServerApiDrogon .

And it turns out that in order to start the server, you just need to implement the handle functions from the ServerApiDrogon class in your class.

Example: We have a yml file with a description of one request - getting data about connecting to a single service

class ResponseError;
// Get Service
class RequestServiceGet;
class ResponseServiceGet;

class ClientApi
{
public:
	template<typename TypeResponse>
	using HandleResponse = std::function<void(std::variant<TypeResponse, ResponseError>&&)>;
public:
	virtual ~Client() = default;
public:
	virtual void send(RequestServiceGet&& request, HandleResponse<ResponseServiceGet>&& handleResponse) = 0;
};

class ClientApiDrogon : public ClientApi
{
public:
	ClientApiDrogon() = delete;
	ClientApiDrogon(const std::string_view&& ip, const uint16_t port);
public:
	virtual void send(RequestServiceGet&& request, HandleResponse<ResponseServiceGet>&& handleResponse) override;
}

class ServerApi
{
public:
	virtual ~ServerApi() = default;
public:
	virtual int run(const std::string_view&& ip, const uint16_t port) = 0;
};

class ServerApiDrogon : public ServerApi
{
public:
	template<typename TypeResponse>
	using HandleResponse = std::function<void(std::variant<TypeResponse, ResponseError>&&)>;
public:
	virtual int run(const std::string_view&& ip, const uint16_t port) override;
protected:
	virtual void handle(RequestServiceGet&& request, HandleResponse<ResponseServiceGet>&& handleResponse) = 0;
}

Now let's say we have several Services and, consequently, several yaml files. We use the script to create our own similar classes (ClientApi and ServerAPI). Now, describing one Service, you can use the ClientApi implementation to access another Service. Since all requests are strictly tied to structures, when changing the API and new file generation during assembly, it will be immediately visible where something needs to be corrected.

p.s. Sample code for the API of one Service. Each service will have its own structures for request and response. Hence its send and handle functions.

Rofl113 avatar Mar 25 '22 14:03 Rofl113

Addition: if there would be more than one request, then each request has its own send and handle.

Rofl113 avatar Mar 25 '22 15:03 Rofl113