Don't get me wrong, I love that once something is on the web, anyone can effortlessly use it on their phone or computer – my most successful projects have been web apps. But I hate that you need to be knowledgeable about both the latest developments and 20 years of historical context to build anything.
QuickServ is inspired by CGI of old: requests are passed on standard input, and responses are passed on standard output. Unlike CGI, QuickServ is designed to work without the user ever touching the command line.
Using this model, QuickServ makes it easy to build web apps, regardless of experience. It delivers ease of use at the expense of speed and security, which makes it powerful for prototyping and hackathons. Check out the examples to see how effortlessly it can be used to bring bad ideas to life. Such bad ideas include (but are not limited to) web applications built in languages like bash and x86 assembly.
Since the main goal of the project is usability, that is the main aspect of the project on which I am looking for feedback. Are the examples clear? Are the error messages clear? Is it easy to set up and install? That kind of thing.
Will edit this comment with more notes as I review it.
First thing I noticed is that Raspberry Pi / Other OS have the example dump into `temp.py` and then indicate that you should request `test.py` (while Win/Mac examples correctly have them create a `test.py` file), so that could be an issue for novices. (Novices running Linux? My son, for one ;) )
EDIT 1: Compile from Source has this issue, too.
EDIT 2: The bit about `directory/index.ext` definitely matches a lot of existing tooling, but not sure if it belongs in a tool that wants to avoid 20+ years of Web cruft? Extension-less files ought to work for the same outcome, right? Or alternatively if the extension would be unambiguous (eg `calculate.*` only matches `calculate.py` it could just be omitted?
EDIT 3: Handwriting query parsing code is not great. If you're not exposing explicit HTTP verbs (GET, POST, etc) or any of the HTTP headers (since I don't see any logic for handling the headers in the stdin) it's inconsistent to have the users hand-parse the query string or body, especially when it's error prone enough that you have more comments than code in that example. It may make sense to just point them at the Python's urllib library (particularly `urllib.parse.parse_qs` for this example to get a basic dictionary to work with).
EDIT 4: I just skimmed through three of the examples (a bash one, a C one, and a TS/Deno one). Besides the custom parsing logic in all of them, and keeping the "rapid prototyping / hacking" mentality of the project in mind (which I do agree is a good thing), what keeps nagging me is: "what's the off-boarding strategy?" Since it is not intended to be secure for real deployments, is it just "rewrite it in your language of choice"? It would be nice if there were examples of what to do if your prototype is ready to be converted into a "real" project with testing, security, etc in mind, even if it was just an essay on all of the stuff that QuickServ didn't do that a real web server needs to handle. Perhaps in the future user-contributed guides for particular languages and frameworks (eg "Convert your Python QuickServ prototype to Django") could also be added to help them move on more easily, since paradoxically for this project the easier it is to migrate away, the more likely people will use it.
Thanks for the feedback! This is very helpful, and I'll be sure to fix these things as soon as I get home from work!
Extension-less files should work fine as an alternative to index.ext pages :) The purpose of index in the demo was to show QuickServ behavior. I like the idea about using calculate.py if there are no other naming collisions for /calculate
As for the query parsing, here is a suggestion: couldn’t you convert that in shell argv automatically? If “name=foo&email=bar” becomes “--name=foo --email=bar” then devs can just use regular argv parsing utils from the language, and the same script can work both from the command line and under QuickServ
Thanks for making this, looks like you indeed can do a lot of fun things with this! Setup was very easy. But it seems IPv6 addresses are not formatted correctly, it should be http://[IP]:port.
Also, have you thought about adding support for websockets (not that I actually need this but I guess it might be fun)?
Great catch, thanks! And thanks for the kind words!
Websockets felt a little out of scope, at least for the first release. But when I end up needing to use them for a project, I might be tempted to add them :)
Obviously I haven’t had time to take deep look into it but I love the ideology. The web development has become so complex without actually putting anything new on the table, the complexity comes from the endless efforts of stitching things together without taking a step back and considering the grand scheme of the things. Web technologists don’t see the forest from the trees and I believe there’s a great potential for simplification.
Bummer, I was going to ask if there is any sandbox for security purpose. But don't get me wrong, this will be extremely useful for casual use cases like home servers or a "sidekick" during development to quickly visualize the results of whatever project you're working on.
To deter using QuickServ in production, it runs on port 42069. Hopefully that makes everyone think twice before entering it into a reverse proxy or port forward config.
I love projects like this. I have recently used `shell2http` for quick server setup that interacts with command line tools like `rclone`. I even wrote a little `shell2discord` library for similar purpose. But `QuickServ` seems to offer more convenience.
A standard shebang will work, too. But one of my (perhaps idealistic) goals was to design QuickServ so that the user need never use the command line. Part of this involves sweeping the PATH and other environment variables under the rug.
Since the QuickServ syntax deviates from the standard shebang, I thought it would be important to highlight front and center in the tutorial.
Thanks for explaining. My thinking was: by (optionally?) allowing the usual extra characters (#!python3 -> #!/usr/bin/env python3) it remains standard, avoiding an unnecessary roadblock for existing scripts and programmer workflows.
PS: I also like your shorter syntax and would be happy if it became a cross platform standard - Shebang 2.0..
Sorry if it wasn't clear from the previous comment, but the version with the usual extra characters will work, too. Scripts with the standard shebang will still be understood by QuickServ. So having a QuickServ script start with
#!/usr/bin/env python3
should be completely valid as far as I have tested. It's just that QuickServ doesn't require the absolute path.
Another, more subtle difference is that QuickServ actually shlexes the shebang into arguments. On Linux, on the other hand, the remainder of the shebang string after the path to the executable is passed as a single argument.
17 comments
[ 4.7 ms ] story [ 47.5 ms ] threadDon't get me wrong, I love that once something is on the web, anyone can effortlessly use it on their phone or computer – my most successful projects have been web apps. But I hate that you need to be knowledgeable about both the latest developments and 20 years of historical context to build anything.
QuickServ is inspired by CGI of old: requests are passed on standard input, and responses are passed on standard output. Unlike CGI, QuickServ is designed to work without the user ever touching the command line.
Using this model, QuickServ makes it easy to build web apps, regardless of experience. It delivers ease of use at the expense of speed and security, which makes it powerful for prototyping and hackathons. Check out the examples to see how effortlessly it can be used to bring bad ideas to life. Such bad ideas include (but are not limited to) web applications built in languages like bash and x86 assembly.
https://github.com/jstrieb/quickserv-examples
Since the main goal of the project is usability, that is the main aspect of the project on which I am looking for feedback. Are the examples clear? Are the error messages clear? Is it easy to set up and install? That kind of thing.
Thanks in advance for taking a look!
First thing I noticed is that Raspberry Pi / Other OS have the example dump into `temp.py` and then indicate that you should request `test.py` (while Win/Mac examples correctly have them create a `test.py` file), so that could be an issue for novices. (Novices running Linux? My son, for one ;) )
EDIT 1: Compile from Source has this issue, too.
EDIT 2: The bit about `directory/index.ext` definitely matches a lot of existing tooling, but not sure if it belongs in a tool that wants to avoid 20+ years of Web cruft? Extension-less files ought to work for the same outcome, right? Or alternatively if the extension would be unambiguous (eg `calculate.*` only matches `calculate.py` it could just be omitted?
EDIT 3: Handwriting query parsing code is not great. If you're not exposing explicit HTTP verbs (GET, POST, etc) or any of the HTTP headers (since I don't see any logic for handling the headers in the stdin) it's inconsistent to have the users hand-parse the query string or body, especially when it's error prone enough that you have more comments than code in that example. It may make sense to just point them at the Python's urllib library (particularly `urllib.parse.parse_qs` for this example to get a basic dictionary to work with).
EDIT 4: I just skimmed through three of the examples (a bash one, a C one, and a TS/Deno one). Besides the custom parsing logic in all of them, and keeping the "rapid prototyping / hacking" mentality of the project in mind (which I do agree is a good thing), what keeps nagging me is: "what's the off-boarding strategy?" Since it is not intended to be secure for real deployments, is it just "rewrite it in your language of choice"? It would be nice if there were examples of what to do if your prototype is ready to be converted into a "real" project with testing, security, etc in mind, even if it was just an essay on all of the stuff that QuickServ didn't do that a real web server needs to handle. Perhaps in the future user-contributed guides for particular languages and frameworks (eg "Convert your Python QuickServ prototype to Django") could also be added to help them move on more easily, since paradoxically for this project the easier it is to migrate away, the more likely people will use it.
Extension-less files should work fine as an alternative to index.ext pages :) The purpose of index in the demo was to show QuickServ behavior. I like the idea about using calculate.py if there are no other naming collisions for /calculate
This is the perfect solution! Thank you so much!
Also, have you thought about adding support for websockets (not that I actually need this but I guess it might be fun)?
Websockets felt a little out of scope, at least for the first release. But when I end up needing to use them for a project, I might be tempted to add them :)
Bummer, I was going to ask if there is any sandbox for security purpose. But don't get me wrong, this will be extremely useful for casual use cases like home servers or a "sidekick" during development to quickly visualize the results of whatever project you're working on.
Why not a standard unix shebang line at top of index.py ?
Since the QuickServ syntax deviates from the standard shebang, I thought it would be important to highlight front and center in the tutorial.
PS: I also like your shorter syntax and would be happy if it became a cross platform standard - Shebang 2.0..
Another, more subtle difference is that QuickServ actually shlexes the shebang into arguments. On Linux, on the other hand, the remainder of the shebang string after the path to the executable is passed as a single argument.
http://mail-index.netbsd.org/netbsd-users/2008/11/09/msg0023...
https://github.com/jstrieb/quickserv/commit/3027a8e91abf4a57...