Skip to content

Instantly share code, notes, and snippets.

@myronmarston
Created February 8, 2013 18:30
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save myronmarston/4740959 to your computer and use it in GitHub Desktop.
Save myronmarston/4740959 to your computer and use it in GitHub Desktop.
What status code should we return for this situation?

What status code should this return?

I'm working on an HTTP-compliant API for a service. We've got a situation where we're not sure what status code to return.

In our system, users create "campaigns" to track data they care about. From the point they create a campaign, it can take a while (e.g. multiple days) before the first batch of data is ready.

During this time before the first batch is ready, when a client an endpoint requesting data for a not-yet ready campaign, what status code should be returned? I can't think of any existing status code that readily applies to this situation. In fact, this situation doesn't even seem to fit into any of the status "families":

  • It's obviously not a 1xx response -- these are more meant more at the protocol layer than for application semantics.
  • 2xx success -- we can't successfully respond to the request because we don't yet have the data the client is requesting.
  • 3xx redirection -- we don't have anywhere to redirect the client to.
  • 4xx client error -- the client hasn't made an error here. the resource simply isn't ready yet.
  • 5xx server error -- it's not a server error, either.

Part of me thinks that 404 is the right response, since the resource cannot (yet) be found...but that kinda implies that the URL is wrong, when the URL is in fact correct--it's just not ready yet. And this isn't really a client error, as I mentioned above.

Another idea is returning a 200 success response, with a payload that is different from the normal success payload--the payload would have an attribute indicating why no requested data is returned. I think this would kinda suck for clients, though; a normal pattern folks follow is:

response = client.make_request
if response.status == 200
  # do something that assumes that the response includes the requested data
end

...but this would pattern would no longer work...clients would now have to do:

response = client.make_request
if response.status == 200 && response['did_it_really_succeed?'] == true
  # do something that assumes that the response includes the requested data
end

...which seems lame.

Thoughts?

@seancribbs
Copy link

On the first submission, 203 Accepted seems appropriate, or 201 Created as long as you're providing a Location from which they can check on their results. When they poll results, it should give a 200 (or 307 Moved Temporarily redirecting to some kind of "status" resource) with whatever status information. Once complete, it could use 200 to return the completed campaign representation with a 200, or use a 301 Moved Permanently to indicate the location of the completed resource.

@steveklabnik
Copy link

You have two options:


The resource exists, but is in a certain state.

GET /campaigns/1

200

{"status":"processing"}

Time.now + 1.week

GET /campaigns/1

200

{"status":"complete", "data":{ ...... }}


Use HTTP 202:

The request has been accepted for processing, but the processing has not been completed.

GET /campaigns/1

202

Time.now + 1.week

GET /campaigns/1

200

{"data":{ ...... }}


Make sense?

@seancribbs
Copy link

When a question like this arises, my general answer is "more resources".

@steveklabnik
Copy link

Oh, and @seancribbs makes a good point: I'd have the initial request return a 201 with a location header pointing to the place you request that gives you the 202.

@seancribbs
Copy link

I always think back to RailsConf 2007 when @sco gave a talk about REST and suggested that for the "edit multiple things at once" case, you might create a temporary resource for the "group of things I'm editing at once", then PUT/POST to that as needed.

@steveklabnik
Copy link

When a question like this arises, my general answer is "more resources".

Fielding has also said this a few times.

@seancribbs
Copy link

@steveklabnik Perhaps, but I tend to take a narrower view of 202 which uses it is a response to a side-effecty action by the client, not to GET/HEAD. 🤷

@steveklabnik
Copy link

The action by the client was creating something with the POST. The server is using its own namespace to say "hey, I made this over there." 🤷

@phiggins
Copy link

phiggins commented Feb 8, 2013

404 seems outright wrong. Either a 202 or a 204 with an explanation in the payload and in the API docs would make sense to me.

@phiggins
Copy link

phiggins commented Feb 8, 2013

The 200 with an explanation in the payload seems analogous to rescuing an exception in ruby and having to look at the message to see what to actually do with it; it's messy and always feels like there should be a more clear distinction made.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment