Nobody knows the future, and preparing for the future is a huge part of software engineering. Sending top-level arrays instead of sending them inside a struct is never the right way.
While I understand the sentiment, I 100% disagree on the 'never' qualifier.
If it is self describing, the overhead could be very very minimal.
So, why would you want to send a plain array without wrapping it in a struct?
Note that even protobufs, which doesn't allow encoding simple types at the top level, still has this debate when deciding whether to encode an array of simple types (inside a struct) or an array of structs (inside a struct). And Google's guidance is to use an array of structs if more data might be needed in the future:
>However, if additional data is likely to be needed in the future, repeated fields should use a message instead of a scalar proactively, to avoid parallel repeated fields.
>// Good: A separate message that can grow to include more fields
https://protobuf.dev/programming-guides/api/#order-independe...
If you're sure that's all you'll ever have to do, then sure. But unless you're 100% certain that the protocol will never evolve further, having a more complex structure allows it to change in a gradual way.