HTTPie – A user-friendly CLI HTTP client
github.com
github.com
Migrated to Curlie [1], `alias http=curlie`, and been happy with it since. Same API, better performance and access to full `curl` flags.
What’s the thinking here? If I ask for the headers, wouldn’t I want that on stdout?
Asking a program for info and then getting that info on stderr seems really bizarre to me.
Is this some historical UNIXism?
You could consider headers to be some sort of debug prints..
The info that you're asking the program for is the response body. You're using `curl` / `curlie` primarily to get the response body and then pipe it to the rest of the command. The headers are ancillary.
If the headers were the info you were asking for, eg when running `curl -D -`, then yes they should get printed to stdout. That is not the case being considered here.
When headers are specifically requests with -i for instance, I agree curlie should print them on stdout. PR accepted ;)
I almost forked it to get both outputs into stdout haha
It would be interesting to create an alternative to `http-prompt` [0], using curlie and go-prompt [1] instead of HTTPie and `prompt_toolkit` [2], respectively.
[0]: https://github.com/eliangcs/http-prompt
[1]: https://github.com/c-bata/go-prompt
[2]: https://github.com/prompt-toolkit/python-prompt-toolkit
# time http google.com >/dev/null 2>&1
real 0m0.337s
user 0m0.259s
sys 0m0.036s
# time curlie google.com >/dev/null 2>&1
real 0m0.042s
user 0m0.011s
sys 0m0.005s
# time curl google.com >/dev/null 2>&1
real 0m0.039s
user 0m0.009s
sys 0m0.004s> If you like the interface of HTTPie but miss the features of curl, curlie is what you are searching for. Curlie is a frontend to curl that adds the ease of use of httpie, without compromising on features and performance. All curl options are exposed with syntax sugar and output formatting inspired from httpie.
So curlie is curl. Thanks for this.
defaults to GET request
http google.com
when json body exists it becomes a POST request http google.com user=65"user=65" is not valid JSON, unless you consider it a single JSON string literal.
HTTPie converts that into a JSON object.
Curl will send the data literally as you send it - if you want to send JSON, give it JSON as the body. If you want to send a "Form POST" quest, give it an encoded query string as the body.
If HTTPie detected that what you gave it was valid JSON, or whatever other media type, and used that to 'guess' the request Content-Type, that would be useful and smart.
But HTTPie not only mangles input, it mangles it in a way that is completely non obvious.
passing it "foo=bar" will send a JSON encoded object like `{"foo": "bar"}`.
passing it "foo=bar&baz=boo" will still send a JSON encoded object like `{"foo": "bar"}`.
So, it knows that ampersand is a field separator, but then promptly ignores all the content after it?
So, no. I call bullshit on "sane defaults" when it mangles data, and silently drops data it's given.
Touché sir, your argument has won the day. /s
After all, this is a discussion forum where regular humans can share their experiences. Not debate club.
echo '{"foo": "bar"}' | http :8000
It also doesn't make it easy to use, because eventually the magic will guess wrong and it will go from magically the right thing even though I passed garbage arguments to completely the wrong thing at the drop of a hat.
An example of a "sane default" where curl falls short might be to enable redirects by default, because that is usually what the user wants (and correct client behavior).
Please explain how a well-defined key-value convention is equitable to "incomplete" or "plain wrong" arguments.
In what way is any of this opaque when it's fully documented and quite easy to follow?: https://github.com/jakubroztocil/httpie#id16
Would Java developers see this and imagine you're passing values for a .properties file?
If you've never seen the tool before, you also wouldn't know how it works at all. Once you hit help for the first time (you know, to actually learn how to use it), knowing it defaults to JSON is pretty much a base truth.
It's entire value proposition seems to be stongly tied to JSON support (2nd highest feature in the pitch at the top).
This is like saying you'd forget jq takes JSON strings...
The first feature pitch is “user-friendly curl alternative with intuitive UI”.
That is probably the most user friendly difference they could make for working with JSON based APIs
The program switches around between HTTP methods, content types, query building, request serialization, etc, at every minor syntactic change to the command line arguments. The fact that a foo=bar implies that the request content type AND the accepted response content type will be set to application/json AND the foo=bar is POSTed as a JSON object isn't a "sane default."
That is not to say it can't be a useful utility. The quirky syntax for query parameters, JSON-serialized request body, etc, can be learned and is quite concise, so after the initial learning curve, it can be used very efficiently.
"Sane defaults" is false advertising, because it implies the least amount of surprise. This tool is the opposite. It is unintuitive but potentially very efficient once learned.
It's a JSON-centric tool made for people who work with APIs that use JSON in very compatible way, with JSON-centric defaults
Changing the accepted type matches behavior of Js HTTP libraries like `request`, where accept and request content types are set in unison by default.
This stuff is all sane defaults for the people who are usually in Postman firing off JSON data to APIs that all look very similar.
"Sane defaults" don't exist in a vacuum, writing (and escaping) properly formatted JSON is a pain (see jq and how the 2nd paragraph in how to even invoke it is dedicated to escaping)
The tool defaults to removing that pain point in a very easy to understand way.
This strikes me as the best of both worlds--you're seamlessly educating the user on what is happening and what they could have done instead.
I'm against dishonest advertising with loaded phrases like "sane defaults" (this term has its place, but it's not here) and "for humans" (this term is always a red flag) when the tool invents a load of unconventional, unintuitive syntax.
Author of the dishonest advertising here ;)
I don't think the fact that the tool introduces a mini language for crafting HTTP requests on the command line contradicts with the statement that the tool also provides what the author believes are sensible defaults (e.g., default to POST when sending data vs. GET when not, default to "prettifying" HTTP messages for human consumptions on the terminal vs. not touching them when the output is redirected, etc.).
"For humans" is meant to highlight the focus of this project on usability and interactive usage, as opposed to curl’s focus on feature-completeness across a number of protocols and non-interactive usage:
> curl is a tool to transfer data from or to a server, using one of the supported protocols (DICT, FILE, FTP, FTPS, GOPHER, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET and TFTP). The command is designed to work without user interaction. [1]
In 99% of cases httpie can assume that I'm making a POST request or a GET request with json or query params. Very rarely will I need to add custom headers, or change the Content-Type.
Yes I can explicitly define the JSON body, headers and method type every time. Or I can use a tool which uses ..... "sane defaults"
Sounds like a curl replacement to me. From wikipedia (https://en.wikipedia.org/wiki/CURL):
"cURL is a command-line tool for getting or sending data including files using URL syntax."
This seems like a small tool with good ergonomics for http/s requests only.
I continue to be surprised by the protocols which curl supports. SMTP, IMAP, SFTP..
The thing I like about curl + jq is that I can easily switch it out for:
TEMPFILE=`mktemp`; curl -s <REQUEST> >$TEMPFILE; python -c "import json; f = open('$TEMPFILE', 'r'); d = json.load(f); <json processing logic and print statement>; f.close()"
and run in my CI environments or ship in docker images for testing purposes.
That said, I do see the potential for a tool like this. What I would like is the ability to manage different profiles for different URLs from the command line. Profiles could just be collections of header specifications - "Authorization: Bearer <blah>" or "Content-Type: application/json"
(Maybe https://github.com/postmanlabs/newman#using-newman-cli ? Didn't know about it until now.)
This is painful. In powershell this is built in and as easy as iwr url/to/json | convertfrom-json | other logic
It's a beefy package, though. Packaged in a docker image on top of alpine:3.10.3 following their installation instructions for alpine: https://gist.github.com/nkashy1/643e7a263054c02e2caceb3912f8...
The image comes in at 178 MB. alpine:3.10.3 is 5.5 MB. An alpine image in which you add bash, bash-doc, and bash-completion clocks in at 13 MB.
Sounds really powerful for personal use, but not an ideal tool for production use (e.g. when you need to spin up a pod on a Kubernetes cluster to debug an issue in production). Will definitely try it out.
xidel url -e 'logic'
and one such xidel call is enough regardless, if the url returns json, xml or html.
It doesn't seem to get much development attention though. There hasn't really been features I find useful added in the past year. The biggest issue is no support for nested JSON bodies, meaning non-trivial API calls end up just as complex as curl.
-d for body
-X for method
—-verbose to see response headers
How much “clearer” could curl get?
-M for Method
-B for Body
-RH for Request Header
you know, so you only have to know the first letter and don't have to remmeber arbitary flags?
I know that it is not that easy, but unix tools do have the problem that often the flags don't make sense on the first glance.
-d for data
-X for execute
There was a reasonable attempt at this already. There are going to opinions on either side. And through regular use the flags would become muscle memory.
Should you be sending HTTP requests to something without knowing precisely what you're doing? httpie just sorta assumes from your arguments what you're trying to do, and for me it has often been wrong. Probably works OK if you have a mostly read-only API.
EDIT: Depends, most of the time I use standard JSON Rest apis, there is not really that much to misassume I think.
Conversely something like jq is trivial to install and use almost anywhere because it is just a binary linked against libc. As a result I use it all the time.
1. pip3 install httpie.
2. python3 -m pip install httpie.
3. sudo pip install httpie.
Finally, it was working. Last week I upgraded to ubuntu 18.04 and surprise, httpie is not working. I didn't bother installing again from pip. Luckily this time, apt repository had a recent version.
Scrolling back through my terminal history, I see that I went through the same struggle with s3cmd.
So yeah, installing anything that requires python is a bit painful. Fortunately, someone in the comments mentioned https://github.com/rs/curlie which is an HTTPie alternative in golang.
Commands are a bit shorter (as it assumes json apparently) but, when working on the terminal, once I wrote my curl command I just keep repeating it anyway or just changing one parameter.
Sure, cURL can do it and if I used it frequently enough, I guess I'd remember how to use it without having to look it up every time, but for my basic and infrequent use, HTTPie is more pleasant to me and I can remember how to use it.
I don’t see any benefit of using this alias
It's not the only tool out there; sometimes cURL makes more sense depending on the context. Use the right tool for the right job!
I use it all the time for just that, the API is so simple I rarely need to check the docs.
But then I realized I'm thinking of libcurl, not curl. So maybe this isn't so bad in Python as a client tool. Does Python 3 still start up really slow though? (honest question)
$ time python3 test.py
Hello world
real 0m0.020s
user 0m0.020s
sys 0m0.000s