1
0
mirror of https://github.com/httpie/cli.git synced 2026-06-20 11:32:56 +02:00

Add nested JSON syntax to the HTTPie DSL (#1224)

* Add support for nested JSON syntax (#1169)

Co-authored-by: Batuhan Taskaya <isidentical@gmail.com>
Co-authored-by: Jakub Roztocil <jakub@roztocil.co>

* minor improvements

* unpack top level lists

* Write more docs

* doc style changes

* fix double quotes

Co-authored-by: Mickaël Schoentgen <contact@tiger-222.fr>
Co-authored-by: Jakub Roztocil <jakub@roztocil.co>
This commit is contained in:
Batuhan Taskaya
2021-12-03 13:17:45 +03:00
committed by GitHub
parent 8fe1f08a37
commit df58ec683e
11 changed files with 503 additions and 12 deletions
+240 -3
View File
@@ -714,6 +714,246 @@ The `:=`/`:=@` syntax is JSON-specific. You can switch your request to `--form`
```
As well as a nested one,
```bash
$ http --offline --print=B pie.dev/post \
result[type]=success
```
```json
{
"result": {"type": "success"}
}
```
Or even multiple levels of nesting.
```bash
$ http --offline --print=B pie.dev/post \
result[status][type]=ok
```
```json
{
"result": {
"status": {
"type": "ok"
}
}
}
```
The declaration also supports creating arrays; which can be either done by simply
assigning the same path multiple times
```bash
$ http --offline --print=B pie.dev/post \
ids:=1 ids:=2
```
```json
{
"ids": [
1,
2
]
}
```
Or using the append suffix `[]`, which would create an array and append the items to the
end of it.
```bash
$ http --offline --print=B pie.dev/post \
ids[]:=1
```
```json
{
"ids": [
1,
2
]
}
```
You can also use indexes to set items on an array,
```bash
$ http --offline --print=B pie.dev/post \
items[0]=terminal items[1]=desktop
```
```json
{
"items": [
"terminal",
"desktop"
]
}
```
If you don't set value for the indexes between, then those will be nullified.
```bash
$ http --offline --print=B pie.dev/post \
items[1]=terminal items[3]=desktop
```
```json
{
"items": [
null,
"terminal",
null,
"desktop"
]
}
```
It is permitted to mix index-access with append actions (`[]`), but be aware that appends will not fill
the voids but instead they will append after the last item.
```bash
$ http --offline --print=B pie.dev/post \
items[1]=terminal items[3]=desktop items[]=web
```
```json
{
"items": [
null,
"terminal",
null,
"desktop",
"web"
]
}
```
If you need to send a top-level list (without any object that is encapsulating it), use the append operator (`[]`) without
any keys.
```bash
$ http --offline --print=B pie.dev/post \
[]:=1 []:=2 []:=3
```
```json
[
1,
2,
3
]
```
Here is a slightly unified example
```bash
$ http --offline --print=B pie.dev/post name=python version:=3 \
date[year]:=2021 date[month]=December \
systems=Linux systems=Mac systems=Windows \
people[known_ids][1]=1000 people[known_ids][5]=5000
```
```json
{
"date": {
"month": "December",
"year": 2021
},
"name": "python",
"people": {
"known_ids": [
null,
"1000",
null,
null,
null,
"5000"
]
},
"systems": [
"Linux",
"Mac",
"Windows"
],
"version": 3
}
```
And here is an even more comprehensive example to show all the features.
```bash
$ http PUT pie.dev/put \
'object=scalar' \ # Object — blank key
'object[0]=array 1' \ # Object — "0" key
'object[key]=key key' \ # Object — "key" key
'array:=1' \ # Array — first item
'array:=2' \ # Array — second item
'array[]:=3' \ # Array — append (third item)
'wow[such][deep][3][much][power][!]=Amaze' # Nested object
```
```http
PUT /person/1 HTTP/1.1
Accept: application/json, */*;q=0.5
Content-Type: application/json
Host: pie.dev
```
### Raw and complex JSON
Please note that with the [request items](#request-items) data field syntax, commands can quickly become unwieldy when sending complex structures.
In such cases, it’s better to pass the full raw JSON data via [raw request body](#raw-request-body), for example:
```bash
$ echo -n '{"hello": "world"}' | http POST pie.dev/post
```
```bash
$ http --raw '{"hello": "world"}' POST pie.dev/post
```
```bash
$ http POST pie.dev/post < files/data.json
```
## Forms
Submitting forms is very similar to sending [JSON](#json) requests.
Often the only difference is in adding the `--form, -f` option, which ensures that data fields are serialized as, and `Content-Type` is set to `application/x-www-form-urlencoded; charset=utf-8`.
It is possible to make form data the implicit content type instead of JSON via the [config](#config) file.
### Regular forms
```bash
$ http --form POST pie.dev/post name='John Smith'
```
```http
POST /post HTTP/1.1
Content-Type: application/x-www-form-urlencoded; charset=utf-8
name=John+Smith
```
### File upload forms
If one or more file fields is present, the serialization and content type is `multipart/form-data`:
```bash
$ http -f POST pie.dev/post name='John Smith' cv@~/files/data.xml
```
The request above is the same as if the following HTML form were submitted:
```html
<form enctype="multipart/form-data" method="post" action="http://example.com/jobs">
<input type="text" name="name" />
<input type="file" name="cv" />
</form>
```
Please note that `@` is used to simulate a file upload form field, whereas `=@` just embeds the file content as a regular text field value.
@@ -731,9 +971,6 @@ $ http --raw '{"hello": "world"}' POST pie.dev/post
```
```http
If one or more file fields is present, the serialization and content type is `multipart/form-data`:
POST / HTTP/1.1
Content-Length: 129
Content-Type: multipart/form-data; boundary=c31279ab254f40aeb06df32b433cbccb