I was a bit tired of reading some toys made with NextJS+Tailwind CSS+Ugly Glossy Theme+Redis docker image, so I just thought that I can write something else for my toy projects like my dev blog.
Anyway, now let's see "why it's simple?"
It's an example from CWIST's readme:
#include <cwist/app.h>
static void hello(cwist_http_request *req, cwist_http_response *res) {
(void)req;
cwist_sstring_assign(res->body, "Hello from CWIST!");
}
int main(void) {
cwist_app *app = cwist_app_create();
cwist_app_get(app, "/", hello);
cwist_app_listen(app, 8080);
cwist_app_destroy(app);
return 0;
}
Some would say it's not that simple. They may say this: #include <cwist.h>
static void hello(cwist_http_app *app) {
cwist_sstring_assign(app->res->body, "Hello from CWIST!");
}
static void setApp(cwist_http_app *app) {
CWIST_APP_CREATE(app);
app->get.append(app->get, "/", hello);
app->ipv4.port = 8080;
}
int main(void) {
CWIST_APP_LISTEN(app);
CWIST_APP_DESTROY(app);
}
Yeah, it looks reasonable at a glance. And this definitely has its own strength. But, some parts are set up by struct members. some are not. some are in ALL CAPS, and some are not. Also, header amalgamation can be easily done by some scripts.Well, in my opinion unifying 'conventions' as many as I can would be a good solution for simplifying code.
When somebody vibe-codes an application without looking at their code (although it's a really bad habit but I've seen somebody who does it) hallucinations are more frequently happened from struct members. However public functions seems quite good to be probabilistically inferenced.
Also, the second one needs more "helper codes". Formally, yep, CWIST's main is kinda bloated, but each step specified in the main function is executed by an explicit wrapper function. It's just like making a lego building.
I know it's not like Drogon. There are really many "mature" C/C++ web frameworks like Drogon, and when you are doing things for production, you cannot use this framework since it's not measured and monitored by security professionals.
Each change should pass sanitizers, cppcheck, http soak test, https c100k test, wasm/wasi smoke test, http/2 test, and so on. Actually I thought that I should do something for http/3, but it's just borrowing many things from lsquic so I just didn't do it.
It's in this external benchmark:
https://web-frameworks-benchmark.netlify.app/
Although it's not "blazingly fast C web framework other than CGI", its performance is fair for developing some small websites. And I am pretty sure it will give you a new perspective to see your code as a "well-structured building".
C4Punks is an organization with many people but some members are quite busy to co-maintain this, so currently I am mainly checking its status. But it's quite hard to read all those modules and refactor, sometimes I couldn't sleep before releasing a new tag.
Any pull requests (including documentations) are welcomed:
https://github.com/c4punks/CWIST/issues
Thanks for reading.