Coder Social home page Coder Social logo

expresscpp / expresscpp Goto Github PK

View Code? Open in Web Editor NEW
86.0 9.0 16.0 746 KB

Fast, unopinionated, minimalist web framework for C++ Perfect for building REST APIs

Home Page: https://gitlab.com/expresscpp/expresscpp

License: MIT License

CMake 20.82% Batchfile 0.06% Shell 2.44% Python 0.96% Dockerfile 1.02% C++ 73.20% JavaScript 1.51%
rest expressjs api cpp17 conan boost great

expresscpp's Introduction

ExpressCpp

Fast, unopinionated, minimalist web framework for C++ Perfect for building REST APIs

Logo of ExpressCpp

Conan pipeline status expresscpp_http License: MIT c++17

Design goals

ExpressCpp aims to be for C++ the same as express for Node.JS including its ecosystem of middlewares and extensions.

Express and Node.JS:

const express = require('express');
const app = express();
app.get('/', (req, res) => res.send('Hello World!'));
const port = 3000;
app.listen(port, () => console.log(`Listening on port ${port}!`));

ExpressCpp:

#include "expresscpp/expresscpp.hpp"
int main() {
  auto expresscpp = std::make_shared<expresscpp::ExpressCpp>();
  expresscpp->Get("/", [](auto /*req*/, auto res) { res->Send("hello world!"); });
  constexpr uint16_t port = 3000u;
  expresscpp->Listen(port,[=](auto /*ec*/) { std::cout << "Listening on port " << port << std::endl; }).Run();
  return 0;
}

Using me

conan

conan remote add expresscpp https://api.bintray.com/conan/expresscpp/expresscpp/

add this to you conan file:

expresscpp/0.11.0@expresscpp/testing

this to your cmake:

find_package(expresscpp)
# ...
target_link_libraries(my_target PRIVATE expresscpp::expresscpp)

vendoring as subdirectory

add_subdirectory(thirdparty/expresscpp)
# ...
target_link_libraries(my_target PRIVATE expresscpp::expresscpp)

installing and using find_package

git clone https://gitlab.com/expresscpp/expresscpp.git
cd expresscpp
mkdir build
cd build
cmake ..
make -j
sudo make install

find_package(expresscpp)
# ...
target_link_libraries(my_target PRIVATE expresscpp::expresscpp)

Build instructions (e.g. ubuntu)

Dependencies

  • boost[asio, beast, uuid]
  • nlohmann/json
  • libfmt
  • gtest (optional)

Conan

sudo apt install -y cmake gcc-9 g++-9 python3-pip

# conan for dependency management
sudo pip3 install conan --upgrade

mkdir -p build
cd build
cmake .. -DEXPRESSCPP_USE_CONAN_DEPENDENCIES=ON
cmake --build . -j

Debian

sudo apt install -y cmake gcc-9 g++-9

# get debian dependencies
sudo apt install -y libboost-all-dev nlohmann-json3-dev libfmt-dev libgtest-dev

mkdir -p build
cd build
cmake ..
cmake --build . -j

Features/Examples

name file
url query params ./example/query_params.cpp
url params ./example/url_params.cpp
auth-like middleware ./example/middleware_auth_like.cpp
log-like middleware ./example/middleware_logger_like.cpp
error handler ./example/error_handler.cpp
variadic middlewares ./example/multiple_handlers.cpp
subrouting ./example/router.cpp

Official Middlewares

name file
static file provider ./example/serve_static.cpp
favicon provider(embedded) ./example/favicon.cpp
  • expresscpp-logger -> TODO
  • expresscpp-grpc-proxy -> TODO
  • expresscpp-reverse-proxy -> TODO
  • expresscpp-basic-auth -> TODO

Similiar projects

name repo
BeastHttp https://github.com/0xdead4ead/BeastHttp/
crow (unmaintained) https://github.com/ipkn/crow
Simple-Web-Server https://gitlab.com/eidheim/Simple-Web-Server
restinio https://github.com/stiffstream/restinio
served https://github.com/meltwater/served

expresscpp's People

Contributors

bachp avatar dependabot[bot] avatar gocarlos avatar kassane avatar tbeu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

expresscpp's Issues

[Question] Status of the project

Hi,

What is the current status of this project? There are a number of TODOs listed on the front page but there hasn't been any repo activity for many months now.

Cheers,

Exceptions

Looks like Handlers should not throw exceptions. I had the hope their error messages will somehow end up in the Error handler. Any ideas or best practices on how to use a exception strategy with expresscpp without adding try/catch to all handlers?

[Proposal] New Accpetor/Listener

I think it's a good idea to have two io_context.
One for accepting new connections (maybe also signal handler),
and one for sessions.

Currently I am using something like this:

int main(int argc, char *argv[]) {
    namespace ba = boost::asio;
    using tcp = ba::ip::tcp;
    // Only for acceptor (maybe also signal handler)
    ba::io_context ctx_accpetor{1};
    tcp::acceptor acceptor(ctx_accpetor);

    std::const_view address{"::"};
    constexpr uint16_t port{8081};

    // Start listen before allocate any resources
    // If we can't bind exit/throw
    tcp::endpoint ep;
    try {
        ep = {ba::ip::make_address(address), port};
        acceptor.open(ep.protocol());
        acceptor.set_option(ba::socket_base::reuse_address{true});
        acceptor.bind(ep);
        acceptor.listen();
    } catch (const std::exception &e) {
        std::cerr << "[" << address <<"]:" << port <<" " << e.what() << '\n';
        return 1;
    }

    auto app = expresscpp::ExpressCpp();
	
    app.Use([](const auto & /*req*/, const auto &res, const Next & /*next*/) {
        res->Json("{}");
    });
	
    auto thn = std::thread::hardware_concurrency;
    // Only for sessions
    ba::io_context ctx_sessions{htn};
    // Keep ctx_sessions running (wait for new sessions to spawn)
    auto work_guard = boost::asio::make_work_guard(ctx_sessions);
    // Start all workers
    std::vector<std::thread> workers;
    workers.reserve(thn);
    for (uint32_t i = 0; i < htn; ++i) {
        workers.emplace_back(std::thread([&ctx_sessions] { ctx_sessions.run(); }));
    }

    // Accpet only on one thread (no need for strand, std::mutex)
    using AcceptHandler = std::function<void(const boost::system::error_code &, ba::ip::tcp::socket)>;
    AcceptHandler handler = [&](const auto &ec, auto peer) {
        if (!ec) {
            std::make_shared<expresscpp::Session>(std::move(peer), &app)->run();
            acceptor.async_accept(ctx_sessions, handler);
        }
    };

    acceptor.async_accept(ctx_sessions, handler);

    // attach signals to ctx_accpetor and thread
    ba::signal_set signal_set(ctx_accpetor, SIGINT, SIGTERM, SIGQUIT);
    signal_set.async_wait([&acceptor](boost::system::error_code const &, int /*sig*/) {
        boost::system::error_code ec;
        acceptor.cancel(ec);
        acceptor.close(ec);
    });

    // Start Accept
    ctx_accpetor.run();
    // Acceptor is cancelled
	
    // Retire guard
    work_guard.reset();
	
    // Wait for all sessions to finish gracefully
    for (auto i = workers.size(); i--;) {
        workers.at(i).join();
    }

    return 0;
}

Don't compile on mingw

I tried to compile this project using msys2/mingw and got the given error:

Output:

-- The CXX compiler identification is GNU 10.2.0
-- Check for working CXX compiler: D:/a/_temp/msys/msys64/mingw64/bin/g++.exe
-- Check for working CXX compiler: D:/a/_temp/msys/msys64/mingw64/bin/g++.exe - works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- PROJECT_VERSION: 0.20.0
-- EXPRESSCPP: not calling conan from cmaka
-- Looking for C++ include pthread.h
-- Looking for C++ include pthread.h - found
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Success
-- Found Threads: TRUE  
-- Found Boost: D:/a/_temp/msys/msys64/mingw64/include (found version "1.73.0") found components: system 
-- Found nlohmann_json: D:/a/_temp/msys/msys64/mingw64/lib/cmake/nlohmann_json/nlohmann_jsonConfig.cmake (found version "3.9.1") 
-- -------------------------------------------------------
-- PROJECT_VERSION:.....................0.20.0
-- EXPRESSCPP_USE_CONAN_DEPENDENCIES:...OFF
-- EXPRESSCPP_BUILD_TESTS:..............OFF
-- EXPRESSCPP_BUILD_EXAMPLES:...........OFF
-- CMAKE_VERSION:.......................3.17.3
-- CMAKE_C_COMPILER:....................
-- CMAKE_CXX_COMPILER:..................D:/a/_temp/msys/msys64/mingw64/bin/g++.exe
-- CMAKE_BUILD_TYPE:....................Release
-- BUILD_SHARED_LIBS:...................ON
-- CLANG_TIDY_EXE:......................
-- -------------------------------------------------------
-- Configuring done
-- Generating done
-- Build files have been written to: C:/_/mingw-w64-expresscpp/src/expresscpp-0.20.0/build-x86_64-w64-mingw32
Scanning dependencies of target expresscpp
[  5%] Building CXX object CMakeFiles/expresscpp.dir/src/path_to_regexp.cpp.obj
[ 10%] Building CXX object CMakeFiles/expresscpp.dir/src/expresscpp.cpp.obj
[ 15%] Building CXX object CMakeFiles/expresscpp.dir/src/layer.cpp.obj
[ 20%] Building CXX object CMakeFiles/expresscpp.dir/src/url.cpp.obj
C:/_/mingw-w64-expresscpp/src/expresscpp-0.20.0/src/expresscpp.cpp: In member function 'void expresscpp::ExpressCpp::HandleRequest(expresscpp::request_t, expresscpp::response_t, std::function<void()>)':
C:/_/mingw-w64-expresscpp/src/expresscpp-0.20.0/src/expresscpp.cpp:150:49: error: 'no_message' is not a member of 'std::errc'; did you mean 'bad_message'?
  150 |       auto ec = std::make_error_code(std::errc::no_message);
      |                                                 ^~~~~~~~~~
      |                                                 bad_message
make[2]: *** [CMakeFiles/expresscpp.dir/build.make:96: CMakeFiles/expresscpp.dir/src/expresscpp.cpp.obj] Error 1
make[2]: *** Waiting for unfinished jobs....
make[1]: *** [CMakeFiles/Makefile2:96: CMakeFiles/expresscpp.dir/all] Error 2
make: *** [Makefile:150: all] Error 2

http_method.cpp won't compile with GCC 10.1.0

GCC 10.1.0 can't compile http_method.cpp.

/usr/include/boost/utility/ostream_string.hpp: In instantiation of ‘std::basic_ostream<charT, traits>& boost::ostream_string(std::basic_ostream<charT, traits>&, const charT*, std::size_t) [with charT = char; traits = std::char_traits<char>; std::size_t = long unsigned int]’:
/usr/include/boost/utility/string_view.hpp:581:37:   required from ‘std::basic_ostream<charT, traits>& boost::operator<<(std::basic_ostream<charT, traits>&, const boost::basic_string_view<charT, traits>&) [with charT = char; traits = std::char_traits<char>]’
/usr/include/boost/beast/http/verb.hpp:150:29:   required from here
/usr/include/boost/utility/ostream_string.hpp:71:29: error: invalid use of incomplete type ‘class std::basic_ostream<char>’
   71 |     typename stream::sentry entry(os);

Adding #include <ostream> resolve the issue

P.S.
I don't known if this is a boost_beast problem.

nice work on the build (not a bug)

I've actually not come across any good examples of including conan as part of the cmake command (cmake running conan). Conan has been a huge hang up for the so called 10x/20x developers on the team to try to figure out the conan incantations (which arguably don't chage, are always the same). Baking this into cmake is a revelation. Also conan doesn't seem to provide adequate non-trivial examples to start with. Thanks for publishing this.

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.