What makes a JSON-RPC 2.0 message a notification, and why can the client never learn that one failed?
answer
- one member left out
- absent is not the same as null
- silence even on error
- batches obey the same rule
basics
~20 sA JSON-RPC 2.0 notification is a Request object with no id member at all. The server MUST NOT reply to it — not on success, not on error, not inside a batch — so the client never sees errors such as invalid params.
solid answer
~40 sA notification is a Request object without an `id` member; leaving `id` out signals that the client has no interest in a Response. The server MUST NOT reply — not on success, not on error, not inside a batch — so the specification itself calls notifications not confirmable: the client never learns of an `Invalid params` or an `Internal error`. The test is absence, not null: `"id": null` is a legal, if discouraged, request id that does get a Response. Notifications suit fire-and-forget signals such as progress or log events; anything whose outcome matters should be a call with an `id`. JSON-RPC 1.0 marked notifications differently, with `id` set to `null`, which is one reason 2.0 discourages null ids.
go deeper
Recall that a notification is a request with no id member and that the server never answers it, whether it succeeds or fails.
Explain absent versus null id, why the specification calls notifications not confirmable, and how notifications behave inside a batch, including the all-notification case.
Judge which messages in a real integration may safely be notifications, and explain how a silent drop after a server change would be noticed when the protocol itself reports nothing.
Set a rule for an estate on when fire-and-forget is acceptable, weighing the saved round trip against the operational cost of failures nobody on the calling side can see.
## The one-member difference In JSON-RPC 2.0 a **notification** is a Request object without an `id` member. Everything else is the same as a call: `jsonrpc` exactly `"2.0"`, a `method`, and optional `params` as an Array or an Object. Leaving the `id` out signals, in the specification's words, the Client's lack of interest in the corresponding Response object. ```json {"jsonrpc": "2.0", "method": "progress.update", "params": {"done": 40, "total": 120}} ``` There is no flag, no special method name and no separate object type; the absence of one member is the whole mechanism. ## What the server must not do The rule is unconditional: the Server **MUST NOT reply to a notification**, including notifications inside a batch request. In practice: - **On success** — no Response. - **On failure** — an unknown method, params that do not fit, a crash inside the method — still no Response. - **Inside a batch** — no Response object for that element in the reply Array; and if every element of the batch was a notification, the Server returns nothing at all, because it MUST NOT return an empty Array. ## Why failures are invisible The specification draws the consequence itself: notifications are **not confirmable by definition**, since they have no Response object, so the Client is not aware of errors such as "Invalid params" or "Internal error". What that means for a running integration: 1. A typo in the method name fails silently. A call would have come back with -32601 Method not found; the notification simply vanishes. 2. A Server release that tightens parameter validation turns notifications that used to work into silent drops, with nothing on the Client's side to show it. 3. Only the Server's own records — its logs or metrics — can reveal the failure, and that is the Server's business, not the protocol's. So the choice between a notification and a call is a choice about whether the Client needs to know the outcome, not about whether it needs the result. ## Absent, null, or a value | `id` in the Request | What it is | What the Server sends | |---|---|---| | absent | a notification | nothing, ever | | `null` | a call (discouraged) | a Response whose `id` is null | | a String or Number | a call | a Response echoing that `id` | The middle row is the trap. The 2.0 specification allows Null as an `id` value but says it SHOULD normally not be used, for two reasons it states: the Server uses a null `id` in Responses when it could not determine the request's `id`, and **JSON-RPC 1.0 used a null `id` for notifications**. A client that writes `"jsonrpc": "2.0"` but keeps 1.0's habit of `"id": null` for notifications will get answers it never expected. ## Objects that merely lack an id Not every object without an `id` is a notification. A notification is a *valid* Request without an `id`; an object that is not a valid Request is an error. The specification's own examples show it: - `{"jsonrpc": "2.0", "method": 1, "params": "bar"}` — no `id`, but `method` is not a String and `params` is not Structured — is answered with `-32600 Invalid Request` and an `id` of null. - Inside a batch, the element `{"foo": "boo"}` gets its own `-32600` Response with a null `id`. A Server that treated every id-less object as a silent notification would hide malformed traffic that the specification expects it to report. ## Choosing between a notification and a call - **Notification:** progress updates, log lines, telemetry, "something changed" hints, where losing one is harmless and the next one supersedes it. - **Call with an `id`:** anything that changes state the Client relies on, anything that can be rejected for bad input, and anything whose failure someone must act on — even if the `result` will be ignored. - **Over a transport that pairs requests with responses**, such as HTTP, the transport may still need to answer something even though JSON-RPC sends no Response; what that is the carrying protocol's or the implementation's decision, since the 2.0 specification defines no HTTP mapping. A notification is cheaper only in the sense that nobody waits; it buys that by giving up every signal about what happened.
- If a JSON-RPC 2.0 client needs to know a call succeeded but has no use for its result, should it still send an id?Yes. The id, not the usefulness of the result, is what makes the server answer. A request with an id gets a Response with either result or error, so the client at least learns about failures such as -32602 Invalid params; a notification leaves it nothing to wait for and nothing to inspect.
- What should a JSON-RPC 2.0 server do with a notification that names a method it does not have?Send nothing. For a call this would be -32601 Method not found, but the server MUST NOT reply to a notification, so the failure can only be recorded on the server's side, for example in its own logs. The client stays unaware, exactly as the specification warns.
A notification is a postcard with no return address: the recipient may act on it, but even if the card is unreadable there is nowhere to send a reply, so the sender learns nothing either way.
saying these in an interview costs you the question
- A JSON-RPC 2.0 notification is a request whose id is set to null.
- The server still sends an error response when a notification fails.
- Inside a batch, each notification gets an empty placeholder response.
- Any object without an id, even a malformed one, is silently ignored as a notification.
- A notification is fine for any call whose result the client ignores.