The short answer is that both are valid because they are unambiguous for the YAML parser. This fact was already pointed by the other answers, but allow me to add some gasoline to this discussion.
YAML uses indentation not only for aesthetics or readability, it has a crucial meaning when composing different data structures and nesting them:
# YAML: # JSON equivalent:
--- # {
one: # "one": {
two: # "two": null,
three: # "three": null
# }
# }
--- # {
one: # "one": {
two: # "two": {
three: # "three": null
# }
# }
# }
As we can see, the simple addition of an indentation level before three
changes its nesting level and removes the previous null
value assignment we had for two
.
This behavior is, however, not consistent when it comes to lists, as they tolerate the removal of a level of indentation that we would naturally expect to occur (as anticipated by the OP), in order to reflect the correct nesting level of the items. It will still work the same way:
# YAML: # JSON equivalent:
--- #
one: #
two: #
- foo # {
- bar # "one": {
# "two": [
# "foo",
# "bar"
# ]
--- # }
one: # }
two: #
- foo #
- bar #
The second form above is somewhat unexpected and breaks with the idea that the indentation level is connected to nesting level, as it is very clear that both two
(an object) and the nested list are written with the same indentation, but are placed at different nesting levels.
What is even worse, it won't work all the times, but only when the list is placed immediately under an object key. Nesting lists inside other lists won't allow freely dropping a level of indentation because, obviously, would bring the nested elements to the parent list:
# YAML: # JSON equivalent:
--- # {
one: # "one": {
two: # "two": [
- # null,
- # [
- # null,
- # null
# ]
# ]
# }
# }
#
--- # {
one: # "one": {
two: # "two": [
- # null,
- # null,
- # null,
- # null
# ]
# }
# }
I know, I know... Don't even start and say that the example above is a bit extreme and could be considered an edge case. They are perfectly valid data structures and prove my point. More complicated situations also happen when mixing objects and nested lists of objects, specially if they have a single key. Not only it may lead to errors in the data structure declaration, but also becomes extremely hard to read.
The following YAML documents are identical:
# YAML: # JSON equivalent
--- #
one: # {
two: # "one": {
- three: foo # "two": [
- bar # {"three": "foo"},
- four: # "bar",
- baz # {
five: # "four": ["baz"],
- fizz # "five": ["fizz", "buzz"],
- buzz # "six": null
six: # }
seven: # ],
# "seven": null
--- # }
one: # }
two: #
- three: foo #
- bar #
- four: #
- baz #
five: #
- fizz #
- buzz #
six: #
seven: #
I don't know about you, but I find the second one much easier to read and follow, specially in a very large document. It's very easy to get lost in the first one, specially when losing the visibility of the beginning of a given object declaration. There is simply no clear connection between the indentation level and the nesting level.
Keeping the indentation level consistently connected to the nesting level is very important to improve readability. Allowing the suppression of an indentation level for lists as optional sometimes is something you have to be very careful about.