2

I'm working on a REST API that requires multiple steps/validations to create a resource, then making a POST /transfer might not create an actual transfer resource (because it needs an extra steps), but is not failing as it will trigger the second step/validation.

In this answer the response is an incomplete or pending transaction with an id, and the resource includes endpoints to finish the transaction, like /transaction/123/commit or in my case /transaction/123/verification/432 where the client can continue, abort or finish the transaction processing.

But what are the possible response codes on that endpoints? Does /transaction/123/commit actually returns 201 because it create the transaction or the transaction is created when it reach pending state?

Vasiliy Faronov
  • 11,840
  • 2
  • 38
  • 49
eloyesp
  • 3,135
  • 1
  • 32
  • 47
  • Are you not able to ask for all the information up front? Could the first POST create a "request" document and return the "request" ID and a second call could begin the processing of the request? – zero298 May 11 '18 at 19:41
  • 1
    No, I can't ask all the information upfront, because some validations are challenges generated with data from the first request. – eloyesp May 11 '18 at 19:53
  • I thought about being hiding other resource, and thought about which name it could have, but I don't see that adding a `request` resource could help here. Something like `transaction_draft` maybe? – eloyesp May 11 '18 at 19:55
  • Neither HTTP nor REST support a multi-step resource creation process OOTB. You can either create intermediary resources similar to GIT commits which depict a transactional view and allow a rollback later on or you have a unique resource which you update (Patch/Put) later on with the new information sent by the client. If the client is interessted in the current state return a 200 OK with the current body else a 201 Created for the initial resource and a 202 Accepted for the remaining parts. Note further that REST cares only for the state of the resource but not the transaction actually. – Roman Vottner May 11 '18 at 21:49

1 Answers1

1

201 (Created)

Status code 201 (Created) indicates the creation of (at least one) new HTTP resource. The URL of the created resource is sent in the response’s Location header.

If POST /transfer creates the resource /transaction/123/commit — that is, if requests to /transaction/123/commit might now succeed where previously you’d have 404 (Not Found) — then it is correct to respond to POST /transfer with 201 and Location: /transaction/123/commit.

If POST /transfer creates several resources, then Location must be the “primary” one (in some sense).

If POST /transaction/123/commit does not create any new resource, then it is incorrect to respond with 201, even if it does create something else (like an internal database record).

If you can’t come up with a URL to send in Location, that probably means you’re not creating any new resource, in which case 201 is incorrect.

Note: Location is always relative to the request URL, not to an “API root” or any such concept you might have. For example, if POST /api/v1/foo/bar creates /api/v1/foo/bar/baz, correct values for Location would include bar/baz and /api/v1/foo/bar/baz, but not /foo/bar/baz.

200 (OK)

Status code 200 (OK) indicates general success. It can be used in most successful responses. It’s a kind of a safe fallback: it doesn’t say much, thus it’s guaranteed not to say much wrong and confuse the client.

If POST /transaction/123/commit succeeds without creating a new resource, then it is correct to respond with 200.

204 (No Content)

Except for responses to GET/HEAD, status code 204 (No Content) is mostly the same as 200. If you use 204 to say something different than 200, you’re probably making up a local convention — same as making up your own status code 275.

Other

IANA maintains a registry of standardized status codes. You can look there for a status code that is standardized to mean exactly what you want to say.

You generally don’t want to use a non-standard status code, or to use a standard status code incorrectly, because that would preclude a uniform interface, which is kind of the whole point of REST.

If you find yourself struggling all the time to uphold a uniform interface, it’s possible that you don’t need REST at all, and should be doing RPC instead.

Community
  • 1
  • 1
Vasiliy Faronov
  • 11,840
  • 2
  • 38
  • 49