Once you understand JSON-RPC’s Bits, you can assemble versions that match the different protocols.
In 1.0 a request object must always have all three fields. If you want a notification, you must set the id to null. The parameter must be an array of positional parameters. So a 1.0 request object always looks like:

Request Object v1
A 1.0 response object contains both a result and an error, but one of them must be null:

Response Object v1
Version 2.0 changed a lot of the protocol designs to be more client-server oriented. It added a new field to identify the specification version, allows reduced fields, and named parameters to be passed.
So a 2.0 request object could look like:

request object v2

request object v2 (no parameters)

request object (notification)

request object (no parameters, notification)
The response object could look like:

response object v2

response object (result only)

response object v2 (error only)
The specification version field was added to make sure the client got back a response type it would expect. The absence of a version field means it cannot reduce the fields and needs to send them with null values like the 1.0 version does.
Reduced fields was included to make a cleaner response structure. Not to reduce the default wire-text length. It also solved the issue of handling a call who’s result was null. Incorrect coding assumptions could cause error handling to trigger on a valid result of null in v1 . Reducing the fields protects against that by providing a cleaner structure and the check of existence vs assumed intent by value.