9 ms·
Crow – C++ Microframework for Web, inspired by Python Flask
- WoodenChair 12y agoThis is going to sound overly critical and judgmental to many - but to me, I just don't understand how you can spend the time involved in developing an entire web framework, and don't have the time to write a couple paragraphs for a README on how to use it and what it's all about along with some examples. I'm not talking full documentation - I'm just talking a few sentences and an example or two. Why bother releasing it before then? Why let people unnecessarily struggle to use it? Maybe somebody posted it here before the author was ready (assuming they're different people).
- adamnemecek 12y agoSee example.cpp. Also the codebase is very small so not much documentation is necessary. Also I'm pretty sure it's more of an exercise than a framework that's intended to be actually used.
- has_bin 12y agoAnd that line you wrote would be a perfect example of what to write. I agree, I find this annoying.
- thezilch 12y agoDifferent authors -- post and repo -- it would appear. But between the example.cpp and unittest.cpp, there is quite a bit there; if you're not familiar with Flaks, it is a very simple web "framework" that basically just provides request, routing, and response primitives. This library also includes a JSON lib, but Flask gets that from Python's batteries. Also, Flask was created as a joke; it obviously took off; but there's something there about not taking it super super serious.
- jeremyjh 12y agoWell the author did not submit this himself; I just stumbled on it and thought it looked cool. I think example.cpp gives you a pretty good idea for what it is about, but in retrospect I should have let him post it when he was ready.
- octo_t 12y agoyou're right, you do sound overly critical and judgmental.
- ipkn 12y agoI'm writer of this project and it's not completed yet. I planned to publish this after finishing basic features and documentations.
- amatheus 12y agoLook really nice! To make the people who will complain about no example in the readme, I would suggest you just copy the example.cpp file into the readme, that'll do until you have more time.
- mempko 12y agoLove the black magic!
- ipkn 12y agothe power of `constexpr'!
- jvickers 12y agoIt looks very convenient for making some relatively simple web services (based on me not knowing much C++, others would get more mileage probably). It looks like the kind of C++ project of a moderately small size that's implementing something that I'm very familiar with already, so I think it will be useful to help me learn C++. I have a couple of questions, and that is what is the reason for only having .h files with no .cpp files in the main part of the microframework? Did something force you to do it that way or was it done like that because you like that code structure?
- Mr_P 12y agoHeader-only libraries have several advantages (see http://en.wikipedia.org/wiki/Header-only http://en.wikipedia.org/wiki/Header-only). Most-notably, they are dead-simple to include with a project, as opposed to having to separately build and link to a shared-library.
- frankzinger 12y ago
- has_bin 12y agoMuch better!
- innover 12y agoI like the technique to generate compile error when there is a mismatch between format string and actual argument list and type - This is what only statically typed language can do and dynamically typed languages like python can't do. Maybe this technique could be applied in printf or other C++ APIs using format string.
- unwind 12y agoNot sure if you're being ironic, but you're describing e.g. GCC's "format" function attribute (https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html#index-g_t_0040code_007bformat_007d-function-attribute-2889 https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html#...), it makes the compiler verify the arguments for printf() and other format-string functions. It's not new, it has been in GCC for quite a number of years (not sure how to check this quickly). UPDATE: I found a list (https://ohse.de/uwe/articles/gcc-attributes.html#func-format https://ohse.de/uwe/articles/gcc-attributes.html#func-format) that says format was added in GCC 2.3-3.4 (whatever the range means). GCC 3.4.0 was released on April 18 2004. Now I'm sad I didn't say "ten years" above, as my original hunch was. :)
- nly 12y agoSpecific to printf and scanf format codes though, not under the control of the programmer.
- nly 12y agoboost::format does away with format codes altogether... you just use '%' place holders. Using constexpr string literal evaluation would be useful for counting them at compile time though.
- daftshady 12y agoIt looks like very interesting project
- rch 12y agoI always wanted to give okws (the c++ server that ran/runs okcupid) a try sometime. It seemed like a great design, if a little tough to get going, because of some dependencies. The license made it a tough sell at the company I was with when it came out too.
- przemoc 12y agoC++ _micro_framework using boost. Just couldn't resist to notice that. ;) (I know that boost consists of many libraries, many of them are header only, etc. so using them doesn't necessarily result in terrible bloat.) Will have a proper look at it later.
- ascotan 12y agoI noticed that to. For C++03 you might need it for scoped_ptr/shared_ptr, but not if you're going to require C++11. If you're going down the -lpthread route you should probably just use them rather than forcing the include on boost threads.
- oscargrouch 12y agoIm not coding much C++ lately, but i think if someone just pick some basic(base, ipc, net, etc..) parts of chromium and create a redistributable library with it.. it would be a very sane and powerful competitor to boost when you are coding in C++ 03..
- mappu 12y agoToday i learned constexpr, enum class, and operator "". Thank you. The full trie implementation caught my eye, are there no suitable alternatives in std or boost? Mixed tabs and spaces (?) cause strange display in github in json.h from 555 through 670 or so. Also at the start of json.h it seems a shame to repeat __builtin_expect rules, how about #if defined() || ?
- sdab 12y agohuh, never seen operator "". Seems to be a c++11 feature. [1] helped me understand it a bit, but Im not sure I see a compelling use case. Does it just provide a shorthand for calling functions on primitive types (and strings) or have I misunderstood? While requiring less characters might it not decrease readability? 1. http://en.cppreference.com/w/cpp/language/user_literal http://en.cppreference.com/w/cpp/language/user_literal
- mike-cardwell 12y agoThe way your routes work mean that a response is expected to be immediately generated and returned. It would be much nicer if a response object was passed to the callback and you could return immediately from the callback, but send a response independently, when you are ready. Kind of like this: CROW_ROUTE(app, "/about") ([](Response res){ res.send("About Crow example"); }); Why you might ask? So you can do this: CROW_ROUTE(app, "/about") ([](Response res){ responses.push_back(res); }); And then some independent method could come along and do the res.send() when it is ready. The connection would hang until res.send() or similar is called on it. There would also be methods on the Response object so you can see if the connection is still alive etc, and maybe the ability to set timeouts directly on the Response object. [edit] This would allow people using your framework to implement long polling without locking up an io_service thread for each connection. It would also make it easier to add support for web sockets etc at a later date. [edit2] This is how NodeJS works. Both a request and a response object is passed to the callback, then you can do for example: function callback (req, res) { setTimeout(function(){ res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello World\n'); }, 5000); }
- mox1 12y agoIf all of this is happening in it's own thread (and there's probably 1 thread per connection), why add the overhead and complexity of something like this?
- mike-cardwell 12y agoI've looked at his code and that is not how it works. It uses boost::asio. You specify how many io_service threads to run. It is not 1 thread per connection. You could easily have 10000 connections spread across 4 threads for example. The threads that handle the connections are the same threads which run the callbacks. You wouldn't want threads being blocked by callbacks that take a long time to run. You'd want to pass those operations off to a different thread pool. So you would want to be able to do what I have suggested. Also, you said this adds complexity and overhead. I dispute that it adds complexity. For most people: "return stuff" vs "res.send(stuff)". And I wouldn't assume that it would add any overhead either. If you disagree, let me know when you've read the code and understand how boost::asio works.
- neuromancer2701 12y agoIt would be interesting to see how this would work with Cheerp(former duetto). Building a frame work on top of that project has been an idea I have been contemplating.
- jxi 12y agoSuper cool! I wonder if any templating framework will be supported (not c++ templates), but I guess sprintf would get us maybe halfway there.
- ivoras 12y agoI don't code much in C++ but recently I started a project just for fun and found it much easier to make a FastCGI app than I anticipated. Yes, there are still some exceedingly low-level stuff to write by yourself, but overall, it's just fine. For example, this is how I handle routing: http://goo.gl/G3jvGp http://goo.gl/G3jvGp A simple static map of regexes and pointers to methods will do the task nicely, and the principle is extendible if I need to create or compose complex apps. There are still things which I would need to encapsulate to make it a rapid development framework (such as QUERY_STRING handling in http://goo.gl/l7Ff75 http://goo.gl/l7Ff75) but it's surprisingly non-painful.
- Sir_Cmpwn 12y agoIs this inviting remote code execution exploits on your websites? One of the reasons most people don't write C/C++ for websites is safety. It's a lot harder to introduce entire categories of bugs when you use safer languages.
- boatzart 12y agoThe way the crow::black_magic::get_parameter_tag works is very impressive. I don't think I ever would have thought to do this with a recursive constexpr like that. I'm a huge fan of providing compiler errors whenever possible, so I'm glad to be able to add this trick to my toolbox.