Armor – Simple HTTP server, supports HTTP/2 and auto TLS(github.com)
github.com
Armor – Simple HTTP server, supports HTTP/2 and auto TLS
https://github.com/labstack/armor
58 comments
TOML is my preferred config file format.
It has all the benefits of JSON and YAML, but it's not so complicated to parse and does not depend on indentation.
https://github.com/toml-lang/toml
It has all the benefits of JSON and YAML, but it's not so complicated to parse and does not depend on indentation.
https://github.com/toml-lang/toml
> It has all the benefits of JSON and YAML...
Well, except that you have to quote strings.
Well, except that you have to quote strings.
JSON (with comments), YAML, and TOML configs can all be read in a standardized format by Ozzo-Config: https://github.com/go-ozzo/ozzo-config
It also supports including multiple config files that merge into one big config. Globbing config files in a directory would be easy.
As an asise, the author of Ozzo-Config is Qiang Xue. He founded the Yii and Yii2 PHP frameworks. Golang code quality in his Ozzo libraries is very good.
It also supports including multiple config files that merge into one big config. Globbing config files in a directory would be easy.
As an asise, the author of Ozzo-Config is Qiang Xue. He founded the Yii and Yii2 PHP frameworks. Golang code quality in his Ozzo libraries is very good.
What's wrong with writing JSON by hand? I've never touched YAML before, but JSON seems pretty clear to me - doesn't feel much different to writing a list naturally.
Is YAML one of those things that proper professional programmers need but us amateurs can botch our way around?
Is YAML one of those things that proper professional programmers need but us amateurs can botch our way around?
Poorly worded by me - it doesn't really matter how hard it is to write - it does matter how compact and readable it is - how long it takes to get an overview of what's wrong.
It's nice if it's easy to write - but the real test is read, comprehend, modify.
JSON merges the worst and most redundant parts of C and lisp.
It's nice if it's easy to write - but the real test is read, comprehend, modify.
JSON merges the worst and most redundant parts of C and lisp.
JSON for configuration is a cute idea that doesn't scale at all. I've personally experienced this in a project at my job. Once the config gets substantially large, it becomes a headache. The real pain is when a sysadmin without any experience in JSON screws up the formatting or tries to change the config and can't decipher the parse errors.
JSON for config is a bad, bad idea - especially if your config will get large.
JSON for config is a bad, bad idea - especially if your config will get large.
[{[[{[{[{[{}]}}}]}]]}]
Spot the typo!
If you think this is stupid because surely everyone uses an editor with automatic scope highlighting etc, I don't think that is the case when you are remotely editing config files via SSH.
Spot the typo!
If you think this is stupid because surely everyone uses an editor with automatic scope highlighting etc, I don't think that is the case when you are remotely editing config files via SSH.
If you work on a team with someone who writes config files like that, I think you've got bigger problems.
vim works via SSH. :)
If you are remotely editing config files, then that is the problem.
In practice, not everybody is managing 10+ identical servers, and manual config + backups works well enough.
I have dozens of small web projects. Part of my project boilerplate is a Fabric file that runs tests and deploys. There's no reason to hand-edit a file on the server unless something is already on fire. And even then . . .
I assume that you already have Apache, your firewall, etc etc set up on the server though? You likely manage OS package updates somehow outside of Fabric?
A fair bit of my stuff co-exists with other things on the same server, so a per-project deployment system couldn't manage everything without occasional conflicts.
A fair bit of my stuff co-exists with other things on the same server, so a per-project deployment system couldn't manage everything without occasional conflicts.
Personally I deploy everything in Docker containers now, so I test a static image and push a bit for bit identical image. (EDIT: Even for individual / one-off setups, yes)
But even if you want to do "manual" changes without Docker, or without a configuration management solution like Puppet etc., I'd do them locally in a git repo or similar and either git pull'ing it or rsyncing it over. Both because it'd mean flexibility in terms of tooling, but also because it makes it easy to actually test it first, or at the very least e.g. syntax check them.
But even if you want to do "manual" changes without Docker, or without a configuration management solution like Puppet etc., I'd do them locally in a git repo or similar and either git pull'ing it or rsyncing it over. Both because it'd mean flexibility in terms of tooling, but also because it makes it easy to actually test it first, or at the very least e.g. syntax check them.
The YAML spec is huge, too large IMO for config files (you can use it while knowing only a subset, but you'll be lost as soon as someone uses a feature you don't know).
I think TOML strikes a good ballance between simplicity and features for config files. It ends up being easy to read and write.
https://github.com/toml-lang/toml
I think TOML strikes a good ballance between simplicity and features for config files. It ends up being easy to read and write.
https://github.com/toml-lang/toml
I wrote a layer around an existing parser that refuses to parse anything except that subset that most people use 99% of the time:
https://github.com/crdoconnor/strictyaml
IMO TOML is syntactically messy, especially when dealing with hierarchical data, and a whole new config format to deal with the fact that YAML has too many features is somewhat unnecessary.
https://github.com/crdoconnor/strictyaml
IMO TOML is syntactically messy, especially when dealing with hierarchical data, and a whole new config format to deal with the fact that YAML has too many features is somewhat unnecessary.
I agree. You often want to parse and/or generate configuration files programmatically. For these cases it's good if parsing and interpretation of the file format can be easily implemented (or is already implemented in high quality). YAML has a quite big featureset and definitely doesn't fall into the "easy to parse" category. I'm also quite happy with using TOML for configuration files for these reasons.
Nod.
TOML is really nice for configuration files.
TOML is really nice for configuration files.
No comments, too tedious to write all the delimiters (mainly string quotes,
but lists and hashes add to that), and trailing comma is disallowed, so moving
list or hash elements around needs more attention.
> Is YAML one of those things that proper professional programmers need but us amateurs can botch our way around?
I really don't understand this attitude. If you already call `json.load(some_string)', there's no difference to change to `yaml.load(some_string)' and go with that. YAML data model is similar to JSON.
JSON is a format mainly for machines, and is somewhat readable for humans. YAML is the reverse: it's mainly for humans, but can be processed by machines.
> Is YAML one of those things that proper professional programmers need but us amateurs can botch our way around?
I really don't understand this attitude. If you already call `json.load(some_string)', there's no difference to change to `yaml.load(some_string)' and go with that. YAML data model is similar to JSON.
JSON is a format mainly for machines, and is somewhat readable for humans. YAML is the reverse: it's mainly for humans, but can be processed by machines.
The single fact that JSON doesn't support comments makes it pretty bad choice for configuration files, where you often want to document why a specific value was chosen for a setting.
Yes - I know that some JSON parsers will allow comments and strip them, but IMHO you shouldn't rely on this, and lots of editors will complain if they encounter any non-standard JSON.
Yes - I know that some JSON parsers will allow comments and strip them, but IMHO you shouldn't rely on this, and lots of editors will complain if they encounter any non-standard JSON.
this is my single largest complaint about JSON... I NEED comments.
I think the idea is that the format lends itself towards being human readable.
If the names/values are chosen well their purpose will be self evident.
If the names/values are chosen well their purpose will be self evident.
Names/values can tell you the what. Comments can tell you the why.
These aren't dip-switches. Description of the logic behind the configuration settings doesn't need to be embedded into the config file. It can be in the manual.
I think you're still missing the point. It's not the description of the logic behind them.
Comments are useful for conveying why a particular value was chosen in this particular config file by some person. For example:
Comments are useful for conveying why a particular value was chosen in this particular config file by some person. For example:
# This is temporarily disabled until TICKET-432 is fixed.
# It should then be turned back on.
feature-that-should-usually-be-enabled: falseAgreed this is helpful when reverse engineering something you don't have documentation for.
But, this is still information that shouldn't be embedded in the config file.
TICKET-432 should say "feature-that-should-usually-be-enabled is set to false while this issue is active. When this is fixed, set it back to true."
But, this is still information that shouldn't be embedded in the config file.
TICKET-432 should say "feature-that-should-usually-be-enabled is set to false while this issue is active. When this is fixed, set it back to true."
That's just asking for the temporary fix to never be reverted because the guy who closed the ticket out didn't read it carefully enough. Or the ticket is marked as "fixed" because the workaround works and it has been open for too long. Keep the documentation next to the fix and someone may eventually find it again. Keep it apart and it can be lost forever.
Yes, the ticket should say that. However, if TICKET-432 is still open, and someone from SysOps comes along to make a change to that config file, how would they know that they shouldn't turn on feature-that-should-usually-be-enabled?
They could read through every open ticket to check, but they're only human, and things can be overlooked. If the comment lives right next to option, it's much harder to miss.
They could read through every open ticket to check, but they're only human, and things can be overlooked. If the comment lives right next to option, it's much harder to miss.
> If the names/values are chosen well their purpose will be self evident.
I don't see how. If I pick a particular value for a config setting, it's obvious what value was chosen, but there's nothing to suggest why that value was chosen.
I don't see how. If I pick a particular value for a config setting, it's obvious what value was chosen, but there's nothing to suggest why that value was chosen.
This reminds me of a a terrible programmer I knew when asked why he had no comments in his code: "inspection of the code should be sufficient".
Not for your code it wasn't.
Not for your code it wasn't.
It takes many years for people to figure out what the right level of commenting is. It's more of an art than a science. Worse, the level of comments depends on the reader. An old veteran may find one distracting that a beginner finds extremely helpful. But they can also be a liability if they aren't maintained with the code or if they make statements about other code that fails to be true after awhile.
A comment like:
# Add 1 to the length of this buffer to work around an off by 1 error in this function in library foo
Can quickly go stale, but sometimes not and could otherwise be accidentally reverted by someone who notices that the buffer is 1 element too long for no apparent reason.
A better comment:
# Add 1 to the length of this buffer to work around an off by 1 error in function foo from library bar (version 1.7.3b circa Nov 1997)
A comment like:
# Add 1 to the length of this buffer to work around an off by 1 error in this function in library foo
Can quickly go stale, but sometimes not and could otherwise be accidentally reverted by someone who notices that the buffer is 1 element too long for no apparent reason.
A better comment:
# Add 1 to the length of this buffer to work around an off by 1 error in function foo from library bar (version 1.7.3b circa Nov 1997)
Tons of useless {} and quotes, useless in a configuration file, I mean. Just rewrite an nginx configuration file in JSON and you'll notice the difference even if nginx has its share of {} and ; Do the same exercise on docker compose yml file.
Actually YAML should be easier to amateurs than to professionals. Pros have tools that deal properly with XML, JSON is a lesser problem.
Actually YAML should be easier to amateurs than to professionals. Pros have tools that deal properly with XML, JSON is a lesser problem.
I agree that JSON isn't a very good syntax for humans to produce. But I think Tom Limoncelli has already written most that needs to be said: http://everythingsysadmin.com/2015/06/toml-vs-json.html
I prefer yaml for deep nesting over toml, though. But whatever the config syntax, comment-preserving parsing would be very nice for config files.
I prefer yaml for deep nesting over toml, though. But whatever the config syntax, comment-preserving parsing would be very nice for config files.
..and here I thought we solved the config library war :( https://github.com/vstakhov/libucl
Why use a static configuration file?
Why not use a real programming language as the "configuration file"? That way, you can install callbacks, etcetera.
Why not use a real programming language as the "configuration file"? That way, you can install callbacks, etcetera.
I've seen several programs where the configuration is just a TCL file or something. It has been a bad idea in every case I have seen thus far.
My favorite configuration file type?
There is some argument for the:
There are libraries to read and write those formats just as easily as JSON or XML or anything else. In fact they're usually easier to use because they don't have to worry about hierarchies or namespaces or any of that nonsense.
Some more thoughts on the subject: http://stackoverflow.com/questions/648246/at-what-point-does...
My favorite configuration file type?
# Comment
key = value
Trying to do more in the configuration file ends up causing more headaches than it solves. Commenting each option means you don't have to flip through the manual to figure out how to get the stupid thing to run.There is some argument for the:
[section]
# Comment
key = value
Style syntax, but I find that for the vast majority of cases making those namespaces is an unnecessary complication. If you have multiple copies of the same option (like multiple VPN endpoints for example), it's almost always a better idea to just split each one up into its own file in a subdirectory instead of trying to stuff all of the info into a single configuration file. People who want to automate stuff later will thank you.There are libraries to read and write those formats just as easily as JSON or XML or anything else. In fact they're usually easier to use because they don't have to worry about hierarchies or namespaces or any of that nonsense.
Some more thoughts on the subject: http://stackoverflow.com/questions/648246/at-what-point-does...
In nodejs you can configure a webserver with a require statement and a couple of function calls. Very flexible.
1) With great power comes great responsibility.
2) Language decision for the application becomes even more consequential to end users.
Why would I want to use this over something like Caddy?
This is based on Echo v3, which is a ultra fast web server framework, but, again, we need to see benchmarks of Armor vs Caddy.
Echo is fast largely because it is based on Go's standard library net/http server, the same as Caddy.
Not really. Echo can use net/http or fasthttp. When using net/http, there is no significant performance gain. All the performance benefit comes from replacing net/http by fasthttp.
Source: https://github.com/labstack/echo/tree/v3
Source: https://github.com/labstack/echo/tree/v3
But Echo v3, which Armor is based on, does not support fasthttp.
Thanks, I missed that!
fasthttp doesn't support HTTP/2 or web sockets yet. If you don't need either, it is a fantastic library.
Source: https://github.com/valyala/fasthttp/blob/master/TODO
Source: https://github.com/valyala/fasthttp/blob/master/TODO
I haven't used any of them, but I would expect the same.
There seem to be a lot of "router" or "middleware" benchmarks nowadays, but from my experience that performance difference is negligible compared to what a different protocol or IO stack implementation can do, e.g. using blocking IO vs. using async IO, buffering and write strategies, etc. If both use net/http I wouldn't expect any difference that really matters in real applications. fasthttp seems to make a difference, but as far as I can read from the documentation it isn't used in Echo v3.
There seem to be a lot of "router" or "middleware" benchmarks nowadays, but from my experience that performance difference is negligible compared to what a different protocol or IO stack implementation can do, e.g. using blocking IO vs. using async IO, buffering and write strategies, etc. If both use net/http I wouldn't expect any difference that really matters in real applications. fasthttp seems to make a difference, but as far as I can read from the documentation it isn't used in Echo v3.
I was going to say, if one wants a go web server with LetsEncrypt there's also https://docs.traefik.io/ . I have heard about Caddy, but had forgotten it is also written in go. So now there's (at least) three.
Good tip! There is also HTTP/2 web servers like H20 (written in C) and ShimmerCat (Haskell). However they are more focused on the problem of fighting latency I believe
[deleted]
can it be used as a library? for a go web app which already uses built-in http server?
As the README mentions, it's built on the Echo[0] framework. You would likely just want to use Echo directly if you want to embed the server in your app.
[0] https://github.com/labstack/echo
[0] https://github.com/labstack/echo
Eh... if only the configuration was in YAML (or TOML)...
+1 for not saying “written in Go” in the title.
Ok, it might be better than Apache's mongrel mix of not-quite and SGML/XML dialect -- but I'd much rather see something like YAML than having to write JSON by hand. I suppose I should just write a compiler (or use one, I'm sure simple YAML maps pretty well 1:1 to simple JSON).