Giter Site home page Giter Site logo

hhy5277 / drogon Goto Github PK

View Code? Open in Web Editor NEW

This project forked from drogonframework/drogon

0.0 1.0 0.0 1.41 MB

Drogon: A C++14/17 based HTTP web application framework running on Linux/macOS/Unix

License: Other

CMake 2.60% Dockerfile 0.12% Shell 0.19% C++ 97.01% C 0.09%

drogon's Introduction

Build Status Codacy Badge Total alerts Language grade: C/C++ Join the chat at https://gitter.im/drogon-web/community Docker image

Overview

Drogon is a C++14/17-based HTTP application framework. Drogon can be used to easily build various types of web application server programs using C++. Drogon is the name of a dragon in the American TV series "Game of Thrones" that I really like.

Drogon's main application platform is Linux. It also supports Mac OS and FreeBSD. Currently, it does not support windows. Its main features are as follows:

  • Use a non-blocking I/O network lib based on epoll (kqueue under MacOS/FreeBSD) to provide high-concurrency, high-performance network IO, please visit the benchmarks page for more details;
  • Provide a completely asynchronous programming mode;
  • Support Http1.0/1.1 (server side and client side);
  • Based on template, a simple reflection mechanism is implemented to completely decouple the main program framework, controllers and views.
  • Support cookies and built-in sessions;
  • Support back-end rendering, the controller generates the data to the view to generate the Html page, the view is described by a "JSP-like" CSP file, the C++ code is embedded into the Html page by the CSP tag, and the drogon command-line tool automatically generates the C++ code file for compilation;
  • Support view page dynamic loading (dynamic compilation and loading at runtime);
  • Provide a convenient and flexible routing solution from the path to the controller handler;
  • Support filter chains to facilitate the execution of unified logic (such as login verification, Http Method constraint verification, etc.) before controllers;
  • Support https (based on OpenSSL);
  • Support WebSocket (server side);
  • Support JSON format request and response, very friendly to the Restful API application development;
  • Support file download and upload;
  • Support gzip compression transmission;
  • Support pipelining;
  • Provide a lightweight command line tool, drogon_ctl, to simplify the creation of various classes in Drogon and the generation of view code;
  • Support NIO-based asynchronously reading and writing database (PostgreSQL and MySQL(MariaDB) database);
  • Support asynchronously reading and writing sqlite3 database based on thread pool;
  • Provide a convenient lightweight ORM implementation that supports for regular object-to-database bidirectional mapping;

A very simple example

Unlike most C++ frameworks, the main program of the drogon application can be kept clean and simple. Drogon uses a few tricks to decouple controllers from the main program. The routing settings of controllers can be done through macros or configuration file.

Below is the main program of a typical drogon application:

#include <drogon/drogon.h>
using namespace drogon;
int main()
{
    app().setLogPath("./");
    app().setLogLevel(trantor::Logger::WARN);
    app().addListener("0.0.0.0", 80);
    app().setThreadNum(16);
    app().enableRunAsDaemon();
    app().run();
}

It can be further simplified by using configuration file as follows:

#include <drogon/drogon.h>
using namespace drogon;
int main()
{
    app().loadConfigFile("./config.json");
    app().run();
}

Drogon provides some interfaces for adding controller logic directly in the main() function, for example, user can register a handler like this in Drogon:

app.registerHttpMethod("/test",
                        [=](const HttpRequestPtr& req,
                            const std::function<void (const HttpResponsePtr &)> & callback)
                            {
                                Json::Value json;
                                json["result"]="ok";
                                auto resp=HttpResponse::newHttpJsonResponse(json);
                                callback(resp);
                            },
                            {Get,"LoginFilter"});

In a scene with dozens of path handlers, isn't it better to disperse them in their respective classes? So unless your logic is very simple, we don't recommend using above interfaces. Instead, we create an HttpSimpleController as follows:

/// The TestCtrl.h file
#pragma once
#include <drogon/HttpSimpleController.h>
using namespace drogon;
class TestCtrl:public drogon::HttpSimpleController<TestCtrl>
{
public:
    virtual void asyncHandleHttpRequest(const HttpRequestPtr& req,const std::function<void (const HttpResponsePtr &)> & callback)override;
    PATH_LIST_BEGIN
    PATH_ADD("/test",Get);
    PATH_LIST_END
};

/// The TestCtrl.cc file
#include "TestCtrl.h"
void TestCtrl::asyncHandleHttpRequest(const HttpRequestPtr& req,
                                      const std::function<void (const HttpResponsePtr &)> & callback)
{
    //write your application logic here
    auto resp = HttpResponse::newHttpResponse();
    resp->setBody("<p>Hello, world!</p>");
    resp->setExpiredTime(0);
    callback(resp);
}

Don't be scared by the code, most of the above programs can be automatically generated by the command line tool drogon_ctl provided by drogon. All the user needs to do is add their own business logic. In the example, the controller returns a Hello, world! string when the client accesses the http://ip/test URL.

For JSON format response, we create the controller as follows:

/// The header file
#pragma once
#include <drogon/HttpSimpleController.h>
using namespace drogon;
class JsonCtrl : public drogon::HttpSimpleController<JsonCtrl>
{
  public:
    virtual void asyncHandleHttpRequest(const HttpRequestPtr &req, const std::function<void(const HttpResponsePtr &)> &callback) override;
    PATH_LIST_BEGIN
    //list path definitions here;
    PATH_ADD("/json", Get);
    PATH_LIST_END
};

/// The source file
#include "JsonCtrl.h"
void JsonCtrl::asyncHandleHttpRequest(const HttpRequestPtr &req,
                                      const std::function<void(const HttpResponsePtr &)> &callback)
{
    Json::Value ret;
    ret["message"] = "Hello, World!";
    auto resp = HttpResponse::newHttpJsonResponse(ret);
    callback(resp);
}

Let's go a step further and create a demo RESTful API with the HttpController class, as shown below (Omit the source file):

/// The header file
#pragma once
#include <drogon/HttpController.h>
using namespace drogon;
namespace api
{
namespace v1
{
class User : public drogon::HttpController<User>
{
  public:
    METHOD_LIST_BEGIN
    //use METHOD_ADD to add your custom processing function here;
    METHOD_ADD(User::getInfo, "/{1}", Get);                  //path is /api/v1/User/{arg1}
    METHOD_ADD(User::getDetailInfo, "/{1}/detailinfo, Get);  //path is /api/v1/User/{arg1}/detailinfo
    METHOD_ADD(User::newUser, "/{1}", Post);                 //path is /api/v1/User/{arg1}
    METHOD_LIST_END
    //your declaration of processing function maybe like this:
    void getInfo(const HttpRequestPtr &req, const std::function<void(const HttpResponsePtr &)> &callback, int userId) const;
    void getDetailInfo(const HttpRequestPtr &req, const std::function<void(const HttpResponsePtr &)> &callback, int userId) const;
    void newUser(const HttpRequestPtr &req, const std::function<void(const HttpResponsePtr &)> &callback, std::string &&userName);
  public:
    User()
    {
        LOG_DEBUG << "User constructor!";
    }
};
} // namespace v1
} // namespace api

As you can see, users can use the HttpController to map paths and parameters at the same time. This is a very convenient way to create a RESTful API application.

After compiling all of the above source files, we get a very simple web application. This is a good start. for more information, please visit the wiki site

drogon's People

Contributors

an-tao avatar bigfish3000 avatar codacy-badger avatar gitter-badger avatar miaogen123 avatar tao-an avatar taoan avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.