
HTTPie – A user-friendly CLI HTTP client - rsapkf
https://github.com/jakubroztocil/httpie
======
rochacon
HTTPie is amazing, but I grew tired of it being "slow", slower than some of my
services response times at least.

Migrated to Curlie [1], `alias http=curlie`, and been happy with it since.
Same API, better performance and access to full `curl` flags.

[1] [https://curlie.io](https://curlie.io)

~~~
kjsthree
> Like curl but unlike httpie, headers are written on stderr instead of
> stdout.

What’s the thinking here? If I ask for the headers, wouldn’t I want that on
stdout?

~~~
rochacon
IDK, that is one of the things that annoys me to be honest, because sometimes
headers get written after the body into the output (idk why, but guess some
buffering and/or parsing+formating lag).

I almost forked it to get both outputs into stdout haha

~~~
poitrus
I get that sometimes too. It should be fixable without having to send headers
to stdout.

------
gitgud
Truly one of the best cli tools out there. The api is concise and flexible,
the --help flag is easy to read. But most importantly, there's _sane_
defaults.

 _defaults to GET request_

    
    
       http google.com
    

_when json body exists it becomes a POST request_

    
    
       http google.com user=65

~~~
stephenr
I don't get how you think that second part is a "sane" default.

"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.

~~~
mike_hock
Completely agree. Opaque magic to "guess what you want" from incomplete or
plain wrong arguments isn't "sane defaults."

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).

~~~
BoorishBears
> Opaque magic to "guess what you want" from incomplete or plain wrong
> arguments isn't "sane defaults."

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](https://github.com/jakubroztocil/httpie#id16)

~~~
detaro
Fairly sure I'd forget all the time that it thinks giving it a syntax that
looks like form-encoded _obviously_ means I want to send a JSON request.

~~~
BoorishBears
key=value is a convention used in so many places that have nothing to do with
form encoding

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...

~~~
stephenr
How many key/value formats commonly used for http request/response
transactions use = ??

The _first_ feature pitch is “user-friendly curl alternative with intuitive
UI”.

~~~
BoorishBears
I'll leave it at this, I'm glad they prioritized not having to escape JSON on
the command line over people who have no idea about how the tool works being
able to guess how to pass form inputs.

That is probably the most user friendly difference they could make for working
with JSON based APIs

------
CGamesPlay
I use HTTPie all the time. It's not a curl replacement, it's a competitor in
the space of CLI HTTP clients. The argument syntax is easier to use than curl,
and it's geared for humans interacting with JSON APIs, including coloring and
pretty printing output.

~~~
zomglings
> I use HTTPie all the time. It's not a curl replacement, it's a competitor in
> the space of CLI HTTP clients.

Sounds like a curl replacement to me. From wikipedia
([https://en.wikipedia.org/wiki/CURL](https://en.wikipedia.org/wiki/CURL)):

"cURL is a command-line tool for getting or sending data including files using
URL syntax."

~~~
buzzkillington
Curl is a lot more than something humans can use from the command line for
http/s requests.

This seems like a small tool with good ergonomics for http/s requests only.

~~~
lol768
> Curl is a lot more than something humans can use from the command line for
> http/s requests.

I continue to be surprised by the protocols which curl supports. SMTP, IMAP,
SFTP..

------
zomglings
As it looks now, I don't see much reason to switch away from curl + jq.

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](https://github.com/postmanlabs/newman#using-newman-cli) ? Didn't know
about it until now.)

~~~
vips7L
>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()"

This is painful. In powershell this is built in and as easy as iwr url/to/json
| convertfrom-json | other logic

~~~
zomglings
Interesting, looks like Linux users can also try out Powershell now:
[https://docs.microsoft.com/en-
us/powershell/scripting/instal...](https://docs.microsoft.com/en-
us/powershell/scripting/install/installing-powershell-core-on-
linux?view=powershell-6)

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...](https://gist.github.com/nkashy1/643e7a263054c02e2caceb3912f82f20)

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.

~~~
vips7L
Probably because it has to include the entire CLR/.net framework. I suppose
that is a concern, but I doubt I'll ever be doing k8s or docker in my career
anytime soon.

------
akvadrako
This is pretty handy. I usually default to httpie for playing with my APIs and
documenting examples - it's much clearer than curl.

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.

~~~
MuffinFlavored
-H for request headers

-d for body

-X for method

—-verbose to see response headers

How much “clearer” could curl get?

~~~
bpfrh
hmmm how about this:

-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.

~~~
microcolonel
> _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._

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.

~~~
bpfrh
I don't send random things, I either look up curl if I need to script
something or I just use postman.

EDIT: Depends, most of the time I use standard JSON Rest apis, there is not
really that much to misassume I think.

------
dig1
For those using Emacs, I'd recommend restclient.el [1]. In Emacs fashion, you
can keep REST API documented in a single (or more) files and evaluate parts
directly in buffer for testing and playing. Throw that on git/mercurial and
you have versioned and documented REST API ;)

[1]
[https://github.com/pashky/restclient.el](https://github.com/pashky/restclient.el)

~~~
t0astbread
Visual Studio Code has a similarly named (seemingly?) API-compatible
extension: [https://github.com/Huachao/vscode-
restclient](https://github.com/Huachao/vscode-restclient)

------
devnonymous
Those who like HTTPie might also like http-prompt[1] which is an interactive
prompt built on top of it.

[1] [http://http-prompt.com/](http://http-prompt.com/)

------
tbrock
Wonderful tool. I’ve said this before but something holding it back is that
you need python to run it and have a python environment set up. Usually this
isn't that big of a deal but it’s just enough friction to make me not reach
for it most of the time.

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.

~~~
divbzero
The Python dependency for HTTPie is handled by most Linux and macOS package
managers [1]. It would be great to have it in Windows package managers as
well.

[1]:
[https://httpie.org/doc#installation](https://httpie.org/doc#installation)

~~~
ducaale
One time I tried to install HTTPie from ubuntu 16.04 apt repository I got an
old version that was not compatible with httpie-jwt-auth so I had to install
it using pip.

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](https://github.com/rs/curlie) which is an
HTTPie alternative in golang.

~~~
chipaca
`snap install http` gets you the latest httpie, fwiw

~~~
ducaale
Snapyy doesn't currently work in windows 10 WSL1 but hopefully will work in
WSL2

------
laurent123456
For someone who doesn't already know curl it might seem easier to use this,
but otherwise it doesn't seem so useful.

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.

~~~
fanf2
I have been using curl for command line http stuff for years and years. I
tried out HTTPie a few months ago for testing a json-flavoured API and I found
it is _amazing_ , it is so much less awkward than piping curl into jq and
struggling with curl’s POST body options

~~~
dkersten
I'm in the same boat. Every time I have had to use curl over the past ~15
years I've had to look up how to do the few basic things I need to do. With
HTTPie, its easy enough that I haven't needed to look anything up after the
first two or three times.

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.

------
dxxvi
There's at least 1 thing curl can do but httpie cannot: anyauth where curl
sends a request and based on the response curl will send another request with
the correct authentication format.

------
dang
The major previous threads are

2018:
[https://news.ycombinator.com/item?id=16243700](https://news.ycombinator.com/item?id=16243700)

2016:
[https://news.ycombinator.com/item?id=12283365](https://news.ycombinator.com/item?id=12283365)

[https://news.ycombinator.com/item?id=11859777](https://news.ycombinator.com/item?id=11859777)

2015:
[https://news.ycombinator.com/item?id=10418882](https://news.ycombinator.com/item?id=10418882)

2014:
[https://news.ycombinator.com/item?id=7890367](https://news.ycombinator.com/item?id=7890367)

2012:
[https://news.ycombinator.com/item?id=4261263](https://news.ycombinator.com/item?id=4261263)

------
t0astbread
A wonderful program. Apparently this is a hot topic but I've found this tool
after growing frustrated with how verbose curl is to type for simply trying
out JSON APIs interactively. Combined with something like fx[1] this is a real
treat.

[1] [https://github.com/antonmedv/fx](https://github.com/antonmedv/fx)

------
izolate
This is the gold standard of CLI tools. Sure, cURL may technically be more
capable, but HTTPie is friendier, more memorable, and clearly built with
developer UX in mind.

~~~
wwn_se
It's the other way around, curl is so good its amost like using the spec.
directly

------
chewz
alias wget='echo "using httpie as wget";http -d'

~~~
buzzerbetrayed
Why would you do this? If you want to use httpie why would type wget? If
you’re pasting a snippet that uses wget, wouldn’t you want it to actually use
wget?

I don’t see any benefit of using this alias

------
fluxsauce
I really like it for functional testing and for describing steps in peer
reviews; it's concise and readable.

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!

------
johnjungles
This is one of the best cli tool I loved it 4 years ago and still do

------
mp3geek
Can it dump all the scripts/images/etc being loaded on a specific website?
(not refering to source)

------
julienfr112
what about performance ?

~~~
petepete
I'd say that its intended use case is to familiarise yourself with APIs and
test out functionality rather than use it in a place where performance really
matters.

I use it all the time for just that, the API is so simple I rarely need to
check the docs.

------
jonny383
When I hear "curl alternative", I think of something low-level, portable and
frankly, something that will compile _almost_ anywhere that has a C compiler.

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)

~~~
Myrmornis
No, Python has never (last decade) had a startup time that is noticeable by
humans when running CLI scripts, unless your CLI script is importing a large
codebase. JVM languages are an example of languages which do start up too
slowly to be attractive for CLI scripting. You are right that python can be
horribly slow to import a large codebase, for example when starting a web
server in a large django project.

~~~
kasey_junk
AOT compilation has come back to JVM languages both on HotSpot and Graal.
There are now lots of ways to remove JVM startup time penalties and most of
them provide for startup times that are as fast as Python independent of code
size.

~~~
asimpletune
Does this apply to scala?

~~~
shakna
Scala Native [0] gives you AOT via LLVM, so it isn't quite the same thing, but
can, in some circumstances, significantly speed up your code.

[0] [https://github.com/scala-native/scala-native](https://github.com/scala-
native/scala-native)

