94

I am trying to use HTTPie to parse to send some nested JSON object, but I can not find how. It is pretty clear how to send a JSON object but not a nested one such as

{ "user": { "name": "john" "age": 10 } }

jotik
  • 17,044
  • 13
  • 58
  • 123
MaatDeamon
  • 9,532
  • 9
  • 60
  • 127

4 Answers4

140

Update for HTTPie 3.0 released in January 2022:

There’s now built-in support for nested JSON using the HTTPie language:

$ http pie.dev/post \
  tool[name]=HTTPie \
  tool[about][homepage]=httpie.io \
  tool[about][mission]='Make APIs simple and intuitive' \
  tool[platforms][]=terminal \
  tool[platforms][]=desktop \
  tool[platforms][]=web \
  tool[platforms][]=mobile 
{
    "tool": {
        "name": "HTTPie",
        "about": {
            "mission": "Make APIs simple and intuitive",
            "homepage": "httpie.io"
        },
        "platforms": [
            "terminal",
            "desktop",
            "web",
            "mobile"
        ]
    }
}

You can learn more about nested JSON in the docs: https://httpie.io/docs/cli/nested-json


Old answer for HTTPie older than 3.0:

You can pass the whole JSON via stdin:

$ echo '{ "user": { "name": "john", "age": 10 } }' | http httpbin.org/post

Or specify the raw JSON as value with :=:

$ http httpbin.org/post user:='{"name": "john", "age": 10 }'
Jakub Roztocil
  • 15,930
  • 5
  • 50
  • 52
  • What about if name is actually a json object and not a table. Hence inside of user you name: {"id": "x", "fn":"xx" } – MaatDeamon May 17 '16 at 12:40
  • What do you mean by "table"? In both of the examples above HTTPie sends the JSON object from you question. – Jakub Roztocil May 18 '16 at 04:04
  • Sorry by table i meant array – MaatDeamon May 18 '16 at 16:51
  • Both of the methods above allow you to specify arbitrary valid JSON data (object, array, boolean, etc.). See the links included in the answer. – Jakub Roztocil May 19 '16 at 02:30
  • In your example the second level is done trough an embedded Json file via bookmarks:=@bookmarks.json. For simplicity if hobbies:='["http", "pies"]' was not an array but an object "hobbies" : {"x": "x", "Y": y}. How would you have done it. My point is i try to use ":=" at the second level and it did not work whenever it was not an array. – MaatDeamon May 19 '16 at 19:06
  • The = and := assignments only allow you to assign non-nested properties. For anything more complex than a simple object it's better to use the first method. – Jakub Roztocil May 20 '16 at 05:42
  • Sorry if i am a bit slow to answer, but by first method you mean: using Echo ? – MaatDeamon May 20 '16 at 15:37
  • Yep, pipe or file redirect – Jakub Roztocil May 20 '16 at 15:47
  • @JuanSalvador the general idea is to pass the data via standard input (stdin). The specific syntax depends on the shell you use. The example above works with many Unix shell, but your shell might use a different syntax for the same thing. – Jakub Roztocil Dec 24 '17 at 16:18
71

I like this way:

$ http PUT localhost:8080/user <<<'{ "user": { "name": "john", "age": 10 }}'

It is preferrable because it has the same prefix as the related commands, and so it is convenient to find the commands with Ctrl+R in bash:

$ http localhost:8080/user/all
$ http GET localhost:8080/user/all # the same as the previous
$ http DELETE localhost:8080/user/234

If you have fishshell, which doesn't have Here Strings, I can propose the following workaround:

~> function tmp; set f (mktemp); echo $argv > "$f"; echo $f; end
~> http POST localhost:8080/user < (tmp '{ "user": { "name": "john", "age": 10 }}')
vikas027
  • 5,282
  • 4
  • 39
  • 51
Nick Linker
  • 1,013
  • 9
  • 10
  • @JuanSalvador we might do some workaround similar for fish I've done for the comment above. – Nick Linker Nov 10 '18 at 09:12
  • 1
    My preference is to use fzf (shell tool), which lets ctrl+R do fuzzy find, so it can find old commands even if the searched text is in a different place in the old command :D – Mike B Jan 21 '21 at 23:22
17

Another approach mentioned in the httpie docs is using a JSON file; this has worked well for me for payloads that are more verbose and deeply nested.

http POST httpbin.org/post < post.json
Zach Valenta
  • 1,783
  • 1
  • 20
  • 35
1

On Windows 10 (cmd.exe) the syntax is a little bit different due to quoting rules. Properties/strings need to be surrounded by double quotes.

http -v post https://postman-echo.com/post address:="{""city"":""london""}"

POST /post HTTP/1.1
Content-Type: application/json
Host: postman-echo.com
User-Agent: HTTPie/2.3.0
{
    "address": {
        "city": "london"
    }
}

You can also send the whole object using echo, and without double quoting.

echo {"address": {"city":"london"} } | http -v post https://postman-echo.com/post
Andrew
  • 8,322
  • 2
  • 47
  • 70