The request is simple, just to add an option to pass raw data like curl
does:
http :/api/user -d 'MyRawData...'
I know that in mostly cases if you are sending JSON or form data, it can be achieved with the _"request items"_, like:
http :/api/hey say=Hello to=me …
And it will converted to the proper format depending of the content type, that is awesome! And if you have something that is not a JSON or form data to send, you can do something like:
echo 'MyRawData...' | http :/api/hey
But this is impractical, the main idea of HTTPie is _cURL-like tool for humans_ , and this case is far of that principle, in fact, curl
is more practical than HTTPie for the previous example. Adding more than one command and pipe them with ugly characters like |
<
just because a simple option is missing doesn't sound _human-friendly_.
What's wrong with add the -d
option to http
?
What's wrong with add the -d option to http?
There'd be nothing _particularly_ wrong with that. I just find piping cleaner and strongly prefer when there is only one way of doing the same thing. Piping exists for this very purpose (i.e. to pass _data_ to programs), and It's easy to understand, universal, and unambiguous. Every decent CLI tool supports piping (with the notable exception of curl
) so you only need to learn the concept once.
Compare:
A universal method for passing request data is through redirected stdin (standard input). Such data is buffered and then with no further processing used as the request body.
-d, --data <data>
(HTTP) Sends the specified data in a POST request to the HTTP server, in the same way that a browser
does when a user has filled in an HTML form and presses the submit button. This will cause curl to pass
the data to the server using the content-type application/x-www-form-urlencoded. Compare to -F,
--form.
-d, --data is the same as --data-ascii. --data-raw is almost the same but does not have a special
interpretation of the @ character. To post data purely binary, you should instead use the --data-binary
option. To URL-encode the value of a form field you may use --data-urlencode.
If any of these options is used more than once on the same command line, the data pieces specified will
be merged together with a separating &-symbol. Thus, using '-d name=daniel -d skill=lousy' would gener-
ate a post chunk that looks like 'name=daniel&skill=lousy'.
If you start the data with the letter @, the rest should be a file name to read the data from, or - if
you want curl to read the data from stdin. Multiple files can also be specified. Posting data from a
file named 'foobar' would thus be done with --data @foobar. When --data is told to read from a file
like that, carriage returns and newlines will be stripped out. If you don't want the @ character to
have a special interpretation use --data-raw instead.
Yes, I agree with you that support piping in a command line tool is a good feature, and also I made a command line tool that supports piping ( Mongotail ), and to be honest I didn't know that curl
doesn't support it. But I think that support both features does not add complexity, because almost all known CLI tools in the Unix ecosystem support both ways. Eg. cat
, grep
, find
, tail
...
The commands you mention do generally accept either a filename argument list or raw input data through stdin
. The don't, however, accept the actual data as arguments. Accepting raw data via an argument is quite uncommon.
(Clarifying what I wrote in an earlier comment: curl
does support stdin but it needs be to explicitly instructed to read it with, for example, --data-binary @-
.)
Came here to file a bug related to this issue, so maybe it's not a bug but working as designed.
I have a bash script I was changing to use "httpie" instead of "curl". The requests are empty-body POSTs to an http server. I run this script by piping it into a docker exec -i ${container} bash -x
.
I had a hard time figuring out that the http POST
command, while it worked fine when run from an interactive shell, was causing the script to immediately exit.
I guess it's something about http
reading stdin in the docker exec
. It seems weird that I have to pipe "echo -n
" to avoid this.
#!/bin/bash
echo "STARTING..."
echo -n | http POST ... # this replaces: curl -XPOST --data-binary '' ...
echo "Without the 'echo -n' above this statement would not be reached."
echo "DONE"
(@jamshid you POST
an empty body simply with http POST httpbin.org/post
. Please read about the specifics of using HTTPie in script — you want to include the --ignore-stdin
option. This is unrelated issue, though, so please open a new issue instead of replying here, if needed.)
Am I right in thinking that 15.1 Request data from a filename covers this issue's original request? I guess this issue can be closed.
As an aside, I wish I'd known about HTTPie before yesterday as I would've avoided 3 hours or so working out why line breaks in my XML file weren't being preserved. (I thought it was my app but it was curl, which requires its --data-binary
option to be used to leave the data alone.) Thanks for HTTPie!
It does not, @DavidOliver . @mrsarm requested to be able to pass a string from parameter, not contents of a file.
+1
Would you accept MR with this feature @jakubroztocil ?
you can just do http POST example.org <<< "foo bar"
or http POST example.org < file.name
http :/api/hey say=Hello to=me …
you can just do
http POST example.org <<< "foo bar"
orhttp POST example.org < file.name
seemed not work for powershell, 'raw body data' | http post :8080/api/events
worked for me on powershell,
but still wanna -d, --data
or something like this to transfer a raw body data
according to the docs you can use a "Bash here string":
http example.com/ <<<'{"name": "John"}'
UI-wise, the option makes sense.
i can't seem to find a way to send an empty json object ({}
) which is a strange but valid use case.
@minusf: i can't seem to find a way to send an empty json object (
{}
) which is a strange but valid use case.
$ echo '{}' | http httpbin.org/post
any way to discard the newline while redirecting?
$ echo 20 | http POST httpbin.org/post
the data filed would be "data": "20\n"
@hahattan you can instruct echo
to not print the trailing newline character with -n
:
$ echo -n foo | http httpbin.org/post
Most helpful comment
you can just do
http POST example.org <<< "foo bar"
orhttp POST example.org < file.name