Git Product home page Git Product logo

feather's Introduction

What is Feather?

Feather is a rapid modern C++ web development framework, written in C++17. The goal of Feather is to develop web applications quickly, with a low barrier to entry. Here is a presentation by Yu Qi on Feather from CppCon 2018: https://youtu.be/DoXXCZJVNeo

Features of Feather

  1. Easy to use
  2. Header only
  3. Cross-platform
  4. High performance
  5. Supports AOP

Components of Feather

  1. HTTP component: cinatra

    cinatra is an easy to use, header only HTTP server. cinatra supports HTTP/1.1, web sockets, and SSL.

  2. Database component: ormpp

    The goal of ormpp is to simplify database programming in C++. ormpp provides an easy to use unified interface, supports multiple databases, and reduces the learning cost of using a database.

    ormpp currently supports three databases: mysql, postgresql, and sqlite. It can be extended to support more databases.

  3. HTML render component: render

    render helps to render HTML pages, such as filling dynamic data into HTML template pages, controlling the UI display, and reusing HTML code.

All the components are independent. Feather just make them work together.

Feather is a classical MVC framework, you just need to focus on your business logic in the controller. In a controller function, you can get HTTP request fields, data, and visit the database. The controller then returns the rendered HTML page to the client.

Build

Feather is based on asio, so it's recommended to install Boost. However this is not strictly necessary, as you can also use AsioStandalone.

The HTTP component cinatra relies on the uuid library, so please install it. It also relies on zlib, but zlib is unnecessary if you want to use gzip. If you want to use gzip please SET(ENABLE_GZIP ON) in CMakeLists.txt. The default value is OFF.

The database component ormpp relies on a database connector.

If you want to use SSL, you also need to install a SSL library. This is not necessary if you don't want to use SSL.

Supported compilers

  • gcc7.1+
  • msvc2017 15.7.1+

Debian Linux

  1. Install mysql client: sudo apt-get install libmysqlclient-dev

  2. Install postgresql client: sudo apt-get install libpq-dev

  3. Install sqlite3: sudo apt-get install libsqlite3-dev

  4. Install uuid: sudo apt-get install uuid

  5. Install zlib: sudo apt-get install zlib1g-dev

  6. Install openssl: sudo apt-get install libssl-dev

CentOS(version 7+ required)

  1. Install mysql client: sudo yum install mysql++-devel.x86_64

  2. Install postgresql: sudo yum install postgresql-devel.x86_64

  3. Install sqlite3: sudo yum install sqlite-devel.x86_64

  4. Install uuid: sudo yum install uuid-devel.x86_64

  5. Install zlib: sudo yum install zlib-devel.x86_64

  6. Install openssl: sudo yum install openssl-devel.x86_64

Windows

  1. Install the mysql connector if you use MySQL
  2. Install the postgresql connector if you use Postgres
  3. Install sqlite3 if you use it

Build

git clone https://github.com/qicosmos/feather.git

git submodule update --init

mkdir build

cd build

cmake ..

make -j

Example

Hello world

#include "feather.h"

using namespace feather;
using namespace ormpp;
using namespace cinatra;

int main() {
	int max_thread_num = std::thread::hardware_concurrency();
	http_server server(max_thread_num);
	server.listen("0.0.0.0", "8080");
	server.set_http_handler<GET, POST>("/", [](request& req, response& res) {
		res.set_status_and_content(status_type::ok, "hello world");
	});

	server.run();
	return 0;
}

The request URL is: http://127.0.0.1:8080/. The response will be: hello world.

You can handle both POST and GET requests from the client in the above example, because you have assigned the verbs POST and GET.

Feather provides GET, POST, DEL, HEAD, PUT, CONNECT, TRACE, OPTIONS for you. You could choose 0-n arbitrary verbs for the request handler function as you wish.

So you could reuse the same request handler function very easily.

HTTP Request

All the fields and data types from a parsed HTTP request are std::string_view. There are no memory copies, no memory moves, and there are enough convenient algorithms. I really love this feature from C++17. I think it should be used in all networking programs.

You can get header fields from the request object:

server.set_http_handler<GET, POST>("/test", [](request& req, response& res) {
	auto name = req.get_header_value("name");
	if (name.empty()) {
		res.render_string("no name");
		return;
	}

	res.render_string("hello world");
});

You can get a header value by a case-insensitive key from the HTTP headers:

auto name = req.get_header_value("name");

If the header does not exist, the returned value will be empty.

There is a similar method get_query_value to get query values:

auto id = req.get_query_value("id");
if (id.empty()) {
	res.render_404();
	return;
}

You can also use get_query_value to get x-www-form-urlencoded value.

HTTP Response

In the above example, you can see:

res.render_string("hello world");

It's a wrapper for:

res.set_status_and_content(status_type::ok, "hello world", res_content_type::string);

It lets you write less code.

Here is res_content_type:

enum class res_content_type{
	html,
	json,
	string,
    none
};

The default res_content_type in set_status_and_content is none. You can set the res_content_type as json:

server.set_http_handler<GET, POST,OPTIONS>("/json", [](request& req, response& res) {
	nlohmann::json json;
    res.add_header("Access-Control-Allow-Origin","*");
	if(req.get_method()=="OPTIONS"){
        res.add_header("Access-Control-Allow-Headers","Authorization");
        res.render_string("");
	}else{
        json["abc"] = "abc";
        json["success"] = true;
        json["number"] = 100.005;
        json["time_stamp"] = std::time(nullptr);
        res.render_json(json);
	}
});

The above example shows how to respond with a JSON string or a normal string. Furthermore you could add headers to the response:

res.render_json(json);
// It is the same as:
res.set_status_and_content(status_type::ok, json, res_content_type::json);

req.get_method() will return HTTP verbs such as POST, GET, OPTIONS, etc.

How do we deal with gzip? Don't worry,we support it already. If you want to use gzip to compress the response string, just set the content_encoding type to gzip:

res.set_status_and_content(status_type::ok, "hello world", res_content_type::none, content_encoding::gzip);

The framework will compress the response string for you. Comfy and sweet. :)

Benchmark

feather's People

Contributors

antimx avatar biless avatar mattharrington avatar maxwell1987 avatar mingxingren avatar qicosmos avatar xmh0511 avatar xxmyjk 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.