0

How to implement conditional request with custom condition that checks order status?

Example:

  • User would sent GET /api/order with header "x-if-ready-for-payment": true.
    • If order is ready for payment, response will be order and status code 200.
    • If order is not ready for payment, response will be error message with status code 412.

Is that the right way or did I completely miss the point of the conditional requirements?

Dharman
  • 30,962
  • 25
  • 85
  • 135
djoloho
  • 39
  • 5
  • Hm... please refrain from asking Stack Overflow [opinion based questions](https://stackoverflow.com/help/dont-ask)! – Mr PizzaGuy Nov 04 '20 at 13:49
  • 2
    @MrPizzaGuy please explain how this is opinion-based? HTTP has specs. – CodeCaster Nov 04 '20 at 13:51
  • If you read his question, he asks `Is that the right way or did I completely miss the point of the conditional requirements?`. That is opinion based. – Mr PizzaGuy Nov 04 '20 at 13:51
  • 3
    @MrPizzaGuy no, it's not. Asking _"is this how conditional requests are meant to be used?"_ is not asking for opinions. – CodeCaster Nov 04 '20 at 13:52
  • sigh i don't want to argue with you about what opinion based questions are, but that is opinion based because he asks if something is done "the correct way", and that could mean different things for different people based off of their opinion. – Mr PizzaGuy Nov 04 '20 at 13:53
  • 1
    @MrPizzaGuy I do want to argue with you about this, because I believe you're wrong, and confusing the OP and other visitors. _"Are you meant to do X with tool Y"_ can be perfectly answered with facts, not opinions, see for example my answer below. Also consider that for example _"Is using a StringBuilder to build XML a good idea?"_ also is an on-topic question, because _"No, XmlWriter is better because it prevents you from making typos in tag names which should match, or forgetting to close a tag"_. Asking whether something is a good idea is not always opinion-based. – CodeCaster Nov 04 '20 at 13:58
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/224092/discussion-between-mr-pizzaguy-and-codecaster). – Mr PizzaGuy Nov 04 '20 at 14:05

2 Answers2

3

Conditional request are basically (but read more here) meant to:

  1. Prevent a (heavy) response payload if the client has a cached representation that's still the same as on the server (e.g. If-None-Match, If-Modified-Since)
  2. Prevent an update if the client has an older version than the server (e.g. (If-Match, If-Unmodified-Since)

See also RFC 7232, Hypertext Transfer Protocol (HTTP/1.1): Conditional Requests:

Conditional GET requests are the most efficient mechanism for HTTP cache updates [RFC7234]. Conditionals can also be applied to state-changing methods, such as PUT and DELETE, to prevent the "lost update" problem: one client accidentally overwriting the work of another client that has been acting in parallel.

It's not meant for your custom business logic. Your x-if-ready-for-payment sounds like you're going to need to invent dozens of new headers that only apply to a single or handful of requests.

Determine what problem you're actually trying to solve, and find a different solution.

Community
  • 1
  • 1
CodeCaster
  • 147,647
  • 23
  • 218
  • 272
3

Is that the right way or did I completely miss the point of the conditional requirements?

CodeCaster has the right idea; I want to try a broader approach

HTTP is an application protocol, whose application domain is the transfer of documents over a network -- Jim Webber, 2011

All of the meta data -- the method tokens, the status codes, the headers -- are of the "transfer of documents" domain.


A key constraint of REST is the uniform interface; all resources on the web understand request messages the same way.

GET /api/order

should have the same semantics as

GET /cute/kitten.jpg

Because the semantics are standardized, and because implementations adhere to those standards, we end up with a bunch of general purpose tools (like web browsers) that can be used in a lot of interesting ways -- you can do your shopping and your banking with the same browser that you use to watch videos on youtube, or ask questions on StackOverflow, and it all "just works".

Introducing headers that are specific to a particular server, or a particular resource, swims against that current - you can write a bespoke client that also understands x-if-ready-for-payment, but now we have are coupling to a custom client, rather than being able to use any HTTP standard aware document reader.

New headers can be standardized, of course - we have protocols for adding new HTTP headers to the IANA registry, but if your headers aren't general purpose achieving adoption is going to be an additional headache after registration.


If the client is asking about order status, then what you should probably be doing is including that status in the representation of the resource, for example

GET /api/order
200 OK
Content-Type: text/plain

x-if-ready-for-payment=true

If the client is trying to change the order status, then you use message semantics that indicate we are trying to change the server's copy of the resource, for example:

POST /api/order
Content-Type: text/plain

x-if-ready-for-payment=true

(The content type in my example is there only to reduce ambiguity, it could just as easily be application/x-www-form-urlencoded, or application/json, or application/prs.djoloho+json or whatever....)

VoiceOfUnreason
  • 52,766
  • 5
  • 49
  • 91