skip to content

In OData 4.01, what do the Prefer preferences return=minimal, return=representation and respond-async ask a service to do?

level: middleimportance: should knowfreq 14%

answer

  1. a request, not a command
  2. Preference-Applied reports back
  3. 204 needs a header naming the entity
  4. 202 only when asked
  5. no effect on GET or DELETE

basics

~20 s

OData's Prefer preferences are RFC 7240 hints: return=minimal asks for no response body, return=representation for the modified resource, respond-async for 202 Accepted plus a status monitor. A service must ignore preferences it does not support, so clients check the status and Preference-Applied.

solid answer

~40 s

`Prefer` carries comma-separated preferences that a service **must ignore** if it does not support them, so a client never assumes one was honoured. **`return=minimal`** and **`return=representation`** apply to `POST`, `PUT`, `PATCH` and action requests (they have no effect on `GET` or `DELETE`): minimal lets the service answer `204 No Content`, representation asks for the modified resource in the body; with neither, services should return the content. A create answered with 204 must still identify the new entity in the `OData-EntityId` header, beside `Location`. **`respond-async`** lets the service answer `202 Accepted` with a `Location` pointing at a status monitor, and it must not answer a data request with 202 unless the client asked. When it applies respond-async it must say so in `Preference-Applied`; for return it may.

go deeper

for a junior

Know that Prefer asks for optional behaviour: return=minimal for no body, return=representation for the saved entity, respond-async for a 202 and a status URL.

for a middle

Explain which methods the return preference affects, the 204 plus OData-EntityId rule on create, and when Preference-Applied is mandatory rather than optional.

for a senior

Build clients that branch on status and Preference-Applied, never on the preference sent, and know OData's status-monitor rules such as AsyncResult and DELETE to cancel.

for a principal

Decide where minimal responses pay off and where the extra GET for server-computed values costs more than the bytes saved.

## Preferences are hints The `Prefer` request header, defined in RFC 7240, lets a client ask for optional behaviour. Its value is a comma-separated list, and OData gives several preferences specific meaning. The ground rule: a service **must ignore** preference values it does not support or know. A preference therefore never causes an error, and a client must not assume it was applied. The service may report what it did in the **`Preference-Applied`** response header (and add `Vary`), and for some preferences that report is mandatory. ```http POST https://sales.example.com/service/Orders Content-Type: application/json Prefer: return=minimal { "CustomerID": "ALFKI", "Status": "Open" } ``` ## return=minimal and return=representation | | `return=minimal` | `return=representation` | no return preference | |---|---|---|---| | Applies to | POST, PUT, PATCH, actions | POST, PUT, PATCH, actions | - | | Typical response | `204 No Content` | `200 OK` / `201 Created` with the resource | content returned (services **should**) | | `Preference-Applied` | may be sent | may be sent | - | - On a `GET` or `DELETE` the return preference has **no effect**. - When a service returns content, it must be the same content a subsequent GET of that resource would return. - A **create** answered with `204` still tells the client where the entity is: `Location` must carry its edit URL (or read URL), and **`OData-EntityId`** must carry its entity-id. The same header is required on an upsert answered with 204. - Inside a batch, return may be set on individual requests; on the batch request itself the service should answer with a 4xx client error. The trade-off is payload size against freshness: minimal saves bandwidth on bulk writes but forces a re-read if the client needs server-computed values such as a new ETag; representation returns those values in one round trip. ## respond-async `respond-async` asks the service to process the request asynchronously. The rules OData adds to the general accept-then-poll pattern: 1. The service **may** answer `202 Accepted`; it **must not** answer a data request with 202 unless the request carried `respond-async`. 2. If it applies the preference, it **must** include `Preference-Applied: respond-async`, as in: ```http HTTP/1.1 202 Accepted Location: https://sales.example.com/service/status/7f3a Preference-Applied: respond-async Retry-After: 5 ``` 3. The 202 response must carry `Location` pointing at a **status monitor** resource, optionally with `Retry-After`. 4. A `GET` on the monitor returns 202 again while work continues, then `200 OK` with the result. In OData 4.01 that 200 must carry the **`AsyncResult`** header holding the final status code of the original request. 5. A `DELETE` on the monitor asks to cancel; a client that waits too long gets `410 Gone` or `404 Not Found`. On a `$batch`, respond-async applies to the batch as a whole, not to its parts. A service can advertise support with the `Capabilities.AsynchronousRequestsSupported` annotation. ## wait, and combining preferences `wait=N` bounds, in seconds, how long the client will wait for synchronous processing. Combined as `Prefer: respond-async, wait=10`, the client says: answer synchronously if you can within ten seconds, otherwise go asynchronous. The specification's own example shows the service may still choose either way, because every preference remains a hint. ## What a robust client does - Branch on the **status code** first: 201 with a body, 204 without, 202 with a monitor. - Read `Preference-Applied` where the service sends it; never assume. - On 204 after a create, take the identity from `OData-EntityId` or `Location` instead of expecting a body. - Do not send return on `GET` or `DELETE` hoping to shape the response; it is ignored. The other OData preferences - change tracking with delta links, a maximum page size, continuing a batch after an error, including annotations - follow the same hint-not-command rule.

  • A POST with Prefer: return=minimal comes back 204 No Content. How does the client learn the new entity's identity?
    From the headers. A create must return `Location` with the new entity's edit URL (or read URL for read-only entities), and a create or upsert answered with 204 must include `OData-EntityId` carrying its entity-id. Server-computed values such as a fresh ETag need a follow-up GET, or `return=representation` next time.
  • What does a client mean by sending Prefer: respond-async, wait=10?
    Respond synchronously if processing finishes within ten seconds, otherwise switch to asynchronous processing with 202 Accepted and a status monitor. Both are hints: the specification's example allows the service to go asynchronous earlier, answer synchronously later, or ignore both preferences.

saying these in an interview costs you the question

  • A service that does not support return=minimal must reject the request with 400.
  • Prefer: return=minimal on a GET trims the response payload.
  • With respond-async the service always answers 202 Accepted.
  • A service may answer 202 Accepted whenever processing is slow, even unasked.
  • After a 204 to a create, the client cannot learn the new entity's URL.
  • A return preference on the $batch request applies to every request inside it.