6

For a RESTful API that I'm creating, I need to have some functionality that get's a resource, but if it doesn't exist, creates it and then returns it. I don't think this should be the default behaviour of a GET request. I could enable this functionality on a certain parameter I give to the GET request, but it seems a little bit dirty.

The main point is that I want to do only one request for this, as these requests are gonna be done from mobile devices that potentially have a slow internet connection, so I want to limit the requests that need to be done as much as possible.

I'm not sure if this fits in the RESTful world, but if it doesn't, it will disappoint me, because it will mean I have to make a little hack on the REST idea.

Does anyone know of a RESTful way of doing this, or otherwise, a beatiful way that doesn't conflict with the REST idea?

gitaarik
  • 42,736
  • 12
  • 98
  • 105
  • I think the consensus is to use HTTP 202. See http://stackoverflow.com/questions/5079367/use-http-status-202-for-asynchronous-operations – Enno Shioji Sep 24 '13 at 08:09
  • I'd probably return a 404 which includes a link to POST to to cause the object to be created in its default state (if, by the time the POST request is sent, the object still doesn't yet exist) – Damien_The_Unbeliever Sep 24 '13 at 08:09

2 Answers2

2

Does the client need to provide any information as part of the creation? If so then you really need to separate out GET and POSTas otherwise you need to send that information with each GET and that will be very ugly.

If instead you are sending a GET without any additional information then there's no reason why the backend can't create the resource if it doesn't already exist prior to returning it. Depending on the amount of time it takes to create the resource you might want to think about going asynchronous and using 202 as per other answers, but that then means that your client has to handle (yet) another response code so it might be better off just waiting for the resource to be finalised and returned.

  • As I said, I don't want it to be the default behaviour of GET. I want the "normal" GET operation to return a 404 if the resource does not exist. Then I want some alternative method that will create the resource if it doesn't exist. As I said I could do this using a parameter in the GET request, such as `createifnotexist=true` or something. I could maybe also do it with a HTTP header. I was however wondering if people have other/better solutions. – gitaarik Sep 24 '13 at 10:43
  • If you need to flag it somehow that you want to do something different the three places you could put something would be the URL, the HTTP header or the message body. As you're doing this with a GET I would suggest that the best place to put it would be a query parameter in the URL. Honestly, though, I think you should choose to either go with your non-standard GET all the time or fall back to two requests, rather than attempt to alter behaviour in this way. Unless it's really obvious when you would send your extra parameter, but in that case encoding it in server-side logic would be safer. –  Sep 24 '13 at 11:56
  • The rfc limits the GET to retrieve the resource, not to create them, no matter if there is or not information, and also would be weird to do a GET and return 201 (Created). If you answer is return 200 (ok) you are not explaining what is happening with the state – Horacio Mar 22 '22 at 16:48
1

very simple:

  1. Request: HEAD, examine response code: either 404 or 200. If you need the body, use GET.
  2. It not available, perform a PUT or POST, the server should respond with 204 and the Location header with the URL of the newly created resource.
Michael-O
  • 18,123
  • 6
  • 55
  • 121
  • Ok sure, fair enough, but I would like to limit it to one request, I'll update my question – gitaarik Sep 24 '13 at 08:21
  • If you want to perform one request, you should simply issue a PUT request which is designed to be idempotent. – Michael-O Sep 24 '13 at 08:33
  • 1
    AFAIK, PUT should be done on the exact URI the resource is living (or will live if it doesn't exist yet). However, I want to fetch a resource based on some parameters, so I don't know the URI and I don't know if it exists. – gitaarik Sep 24 '13 at 08:42
  • 1
    That's correct. Then you cannot use a PUT. I do not think that this is going to be possible with a single request. – Michael-O Sep 24 '13 at 09:20