1/6

The id member is a switch. A Request object with no id is a notification: the server runs the handler and MUST NOT send a response object — not a result, not even an error.

That is the contract, not an optimisation. A client that sent a notification is not reading for a reply, and writing one desynchronises a pipelined connection: every subsequent response is matched against the wrong request.

The spec is careful about one distinction people flatten:

| body | meaning | | --- | --- | | {"jsonrpc":"2.0","method":"log"} | notification — no reply | | {"jsonrpc":"2.0","method":"log","id":null} | a call whose id happens to be null — reply with "id":null |

An absent id and an explicit null id are different requests.