Is it REST if I pass the following URI /apps/{id}?control=start - api

I'm in the process of designing a REST API for our web app.
POST > /apps > Creates an app
PUT > /apps/{id} > Updates the app
I want to start the apps.
Is this REST and if not, how can I make it more RESTful?
POST > /apps/{id}?control=start
Sun Cloud API does this: http://kenai.com/projects/suncloudapis/pages/CloudAPISpecificationResourceModels
Or is it better to:
2. PUT /apps/{id} and include a status parameter in the response Json/XML?
3. POST /apps/{id} and include a status parameter in the response Json/xml?
4. POST /apps/start?app={id}

I think the right question here is more whether the HTTP verbs are being used as intended rather than whether the application is or is not as RESTful as possible. However, these days the two concepts are pretty much the same.
The thing about PUT is that whatever you PUT you should be able to immediately GET. In other words, PUT does a wholesale replacement of the resource. If the resource stored at apps/5 is something that has a "control" attribute as part of its state, then the control=start part should be part of the representation you put. If you want to send just the new piece of the resource, you are doing a PATCH, not a PUT.
PATCH is not widely supported, so IMHO you should use a POST. POST has no requirements of safety or idempotency; generally you can do whatever you want with a POST (more or less), including patching parts of a resource. After all that is what you do when you create a new item in a collection with a POST. Updating a portion of a resource is not really much different.
Generally though you POST new data in the request body, not as query parameters. Query parameters are used mostly for GETs, because you are, well, querying. :)

Does starting an app changes it state? (to "running", for example) If it does what you're actually doing is updating the state of the resource (application). That seems like a good use for the PUT operation. Although as Ray said, if control is part of the state of the resource, the body of the PUT request should contain the state you're updating. I believe a partial update would be possible (CouchDB uses this).
On the other hand, if starting an app means creating a new resource (representing the app execution, for example), the POST method would be a great fit. You could have something like this:
POST /app/1/start
Which would result in a HTTP/1.1 201 Created. Then, to access the information on the created execution, you could use a URL like this:
GET /app/1/execution/1
To me, this would seem like a good "Restful" approach. For more information, check out this article.

PUT apps/{id}
I would PUT the app to update it's status from off to on

I like to do something like,
POST /runningapps?url=/app/1

Related

Restful api - Is it a good practice, for the same upsert api, return different HttpStatusCode based on action

So i have one single http post API called UpsertPerson, where it does two things:
check if Person existed in DB, if it does, update the person , then return Http code 200
if not existed in DB, create the Person, then return http 201.
So is it a good practices by having the same api return different statusCode (200,201) based on different actions(update, create)?
This is what my company does currently , i just feel like its weird. i think we should have two individual api to handle the update and create.
ninja edit my answer doesn't make as much sense because I misread the question, I thought OP used PUT not POST.
Original answer
Yes, this is an excellent practice, The best method for creating new resources is PUT, because it's idempotent and has a very specific meaning (create/replace the resource at the target URI).
The reason many people use POST for creation is for 1 specific reason: In many cases the client cannot determine the target URI of the new resource. The standard example for this is if there's auto-incrementing database ids in the URL. PUT just doesn't really work for that.
So PUT should probably be your default for creation, and POST if the client doesn't control the namespace. In practice most APIs fall in the second category.
And returning 201/200/204 depending on if a resource was created or updated is also an excellent idea.
Revision
I think having a way to 'upsert' an item without knowing the URI can be a useful optimization. I think the general design I use for building APIs is that the standard plumbing should be in place (CRUD, 1 resource per item).
But if the situation demands optimizations, I typically layer those on top of these standards. I wouldn't avoid optimizations, but adopt them on an as-needed basis. It's still nice to know if every resource has a URI, and I have a URI I can just call PUT on it.
But a POST request that either creates or updates something that already exists based on its own body should:
Return 201 Created and a Location header if something new was created.
I would probably return 200 OK + The full resource body of what was updated + a Content-Location header of the existing resource if something was updated.
Alternatively this post endpoint could also return 303 See Other and a Location header pointing to the updated resource.
Alternatively I also like at the very least sending a Link: </updated-resource>; rel="invalidates" header to give a hint to the client that if they had a cache of the resource, that cache is now invalid.
So is it a good practices by having the same api return different statusCode (200,201) based on different actions(update, create)?
Yes, if... the key thing to keep in mind is that HTTP status codes are metadata of the transfer-of-documents-over-a-network domain. So it is appropriate to return a 201 when the result of processing a POST request include the creation of new resources on the web server, because that's what the current HTTP standard says that you should do (see RFC 9110).
i think we should have two individual api to handle the update and create.
"It depends". HTTP really wants you to send request that change documents to the documents that are changed (see RFC 9111). A way to think about it is that your HTTP request handlers are really just a facade that is supposed to make your service look like a general purpose document store (aka a web site).
Using the same resource identifier whether saving a new document or saving a revised document is a pretty normal thing to do.
It's absolutely what you would want to be doing with PUT semantics and an anemic document store.
POST can be a little bit weird, because the target URI for the request is not necessarily the same as the URI for the document that will be created (ie, in resource models where the server, rather than the client, is responsible for choosing the resource identifier). A common example would be to store new documents by sending a request to a collection resource, that updates itself and selects an identifier for the new item resource that you are creating.
(Note: sending requests that update an item to the collection is a weird choice.)

How do I design a REST call that is just a data transformation?

I am designing my first REST API.
Suppose I have a (SOAP) web service that takes MyData1 and returns MyData2.
It is a pure function with no side effects, for example:
MyData2 myData2 = transform(MyData myData);
transform() does not change the state of the server. My question is, what REST call do I use? MyData can be large, so I will need to put it in the body of the request, so POST seems required. However, POST seems to be used only to change the server state and not return anything, which transform() is not doing. So POST might not be correct? Is there a specific REST technique to use for pure functions that take and return something, or should I just use POST, unload the response body, and not worry about it?
I think POST is the way to go here, because of the sheer fact that you need to pass data in the body. The GET method is used when you need to retrieve information (in the form of an entity), identified by the Request-URI. In short, that means that when processing a GET request, a server is only required to examine the Request-URI and Host header field, and nothing else.
See the pertinent section of the HTTP specification for details.
It is okay to use POST
POST serves many useful purposes in HTTP, including the general purpose of “this action isn’t worth standardizing.”
It's not a great answer, but it's the right answer. The real issue here is that HTTP, which is a protocol for the transfer of documents over a network, isn't a great fit for document transformation.
If you imagine this idea on the web, how would it work? well, you'd click of a bunch of links to get to some web form, and that web form would allow you to specify the source data (including perhaps attaching a file), and then submitting the form would send everything to the server, and you'd get the transformed representation back as the response.
But - because of the payload, you would end up using POST, which means that general purpose components wouldn't have the data available to tell them that the request was safe.
You could look into the WebDav specifications to see if SEARCH or REPORT is a satisfactory fit -- every time I've looked into them for myself I've decided against using them (no, I don't want an HTTP file server).

RESTful way of getting a resource, but creating it if it doesn't exist yet

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?
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.
very simple:
Request: HEAD, examine response code: either 404 or 200. If you need the body, use GET.
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.

Confused about Http verbs

I get confused when and why should you use specific verbs in REST?
I know basic things like:
Get -> for retrieval
Post -> adding new entity
PUT -> updating
Delete -> for deleting
These attributes are to be used as per the operation I wrote above but I don't understand why?
What will happen if inside Get method in REST I add a new entity or inside POST I update an entity? or may be inside DELETE I add an entity. I know this may be a noob question but I need to understand it. It sounds very confusing to me.
#archil has an excellent explanation of the pitfalls of misusing the verbs, but I would point out that the rules are not quite as rigid as what you've described (at least as far as the protocol is concerned).
GET MUST be safe. That means that a GET request must not change the server state in any substantial way. (The server could do some extra work like logging the request, but will not update any data.)
PUT and DELETE MUST be idempotent. That means that multiple calls to the same URI will have the same effect as one call. So for example, if you want to change a person's name from "Jon" to "Jack" and you do it with a PUT request, that's OK because you could do it one time or 100 times and the person's name would still have been updated to "Jack".
POST makes no guarantees about safety or idempotency. That means you can technically do whatever you want with a POST request. However, you will lose any advantage that clients can take of those assumptions. For example, you could use POST to do a search, which is semantically more of a GET request. There won't be any problems, but browsers (or proxies or other agents) would never cache the results of that search because it can't assume that nothing changed as a result of the request. Further, web crawlers would never perform a POST request because it could not assume the operation was safe.
The entire HTML version of the world wide web gets along pretty well without PUT or DELETE and it's perfectly fine to do deletes or updates with POST, but if you can support PUT and DELETE for updates and deletes (and other idempotent operations) it's just a little better because agents can assume that the operation is idempotent.
See the official W3C documentation for the real nitty gritty on safety and idempotency.
Protocol is protocol. It is meant to define every rule related to it. Http is protocol too. All of above rules (including http verb rules) are defined by http protocol, and the usage is defined by http protocol. If you do not follow these rules, only you will understand what happens inside your service. It will not follow rules of the protocol and will be confusing for other users. There was an example, one time, about famous photo site (does not matter which) that did delete pictures with GET request. Once the user of that site installed the google desktop search program, that archieves the pages locally. As that program knew that GET operations are only used to get data, and should not affect anything, it made GET requests to every available url (including those GET-delete urls). As the user was logged in and the cookie was in browser, there were no authorization problems. And the result - all of the user photos were deleted on server, because of incorrect usage of http protocol and GET verb. That's why you should always follow the rules of protocol you are using. Although technically possible, it is not right to override defined rules.
Using GET to delete a resource would be like having a function named and documented to add something to an array that deletes something from the array under the hood. REST has only a few well defined methods (the HTTP verbs). Users of your service will expect that your service stick to these definition otherwise it's not a RESTful web service.
If you do so, you cannot claim that your interface is RESTful. The REST principle mandates that the specified verbs perform the actions that you have mentioned. If they don't, then it can't be called a RESTful interface.

should I put connecting words in my restful api or not?

Let's say I have a controller that takes three parameters:
class Dog {
function tell (dogId, commandId, rewardId) {
// blah
}
}
My url for accessing that might be:
mysite.com/dog/tell/1/2/3
In that case, you have to remember that the parameters map to dogId, commandId & rewardId in that order. The other way to go might be something like:
mysite.com/dog/tell/1/command/2/reward/3
or for even more clarity (but probably more jiggery-pokery with your framework):
mysite.com/tell/dog/1/command/2/reward/3
Which is better? Which is more common? At first blush it seems like clearer is better. However, you still have to remember what the order of the parameters is, and now you have to remember the key-words, as well. ("Was it 'dog/command/reward' or 'command/dog/reward' or 'dog/to/for' or...?")
Thoughts? References? :)
You don't appear to be creating a RESTful API here. REST APIs use URIs to denote resources, not operations (tell looks like an operation to me). Operations on resources are defined by an interface that is common to all resources. I assume you're designing a REST API using HTTP, so your common interface is defined by the HTTP verbs GET, POST, PUT, DELETE, etc.
So, rather than define our service in terms of the operation tell, lets start by thinking about a resource: dog. As a client, lets assume I'm looking for Rover the dog. My first interaction with your service might be a request like:
GET mysite.com/dogs?q=Rover
Within the response to this request, lets assume that I am given a URL of a resource that represents Rover the dog: mysite.com/dogs/3759
Now, lets find out the state of Rover the dog:
GET mysite.com/dogs/3739
In the response, I see that Rover the dog is alive, awake and standing up (i.e. the response tells me the state of Rover the dog). The response also includes forms which I can use to cause a transition in the state of this resource (i.e. the response tells me how to make Rover change state).
Now, the next step is to tell Rover to do something. We want Rover's state to transition from standing to sitting (lets assume that we can't simply update Rovers state from standing to sitting, we can only issue a command which Rover can choose to follow - just like a real dog!). Lets post a sit command to Rover:
POST mysite.com/dogs/3739
<command name="sit"/>
We can think of the command as a resource in it's own right - it has a 'name' (sit) an issuer (me), a dog (Rover) and it may also be followed or unfollowed (depending on the dog's mood). Now in my response to this POST I get the following information
Status : 201 (Created)
Location: mysite.com/dogs/3739/commands/1299
The status tells me that this data has been received by Rover and it has caused the creation of a new resource (our command). If we want to get the state of this command, we can see it by making a request to the URL given in the Location header. Let's do that, and find out about our newly created command:
GET mysite.com/dogs/3739/commands/1299
Now the response will tell me the state of this command. Let's assume we're in luck: the command has been followed (the representation returned for this resource includes some information like followed=true). The response also includes a link back to the resource that represents Rover (the dog to which the command was issued).
Finally, when we request the state of the resource that represents Rover:
GET mysite.com/dogs/3739
We see from the response that a state transition has occurred, and we are now told that Rover is 'sitting'. The response may also include a reference to the list of commands that Rover has been issue to-date in the form of a link to this URI:
mysite.com/dogs/3739/commands/
This is IMO much closer to a RESTful model. The domain you've chosen here may make things harder to explain and understand I think. A 'command' resource is confusing and sounds very RPC, but the word 'command' is really just used because we're talking about pets. In reality a 'command' is simply a message that you send to a dog. When we substitute the word 'command' for the word 'message', it's easier to see that a message is a resource that certainly has a state.
So in short (tl;dr):
give URIs to resources, not operations
create/update resources (cause state transitions) by sending data (not 'invoking operations')
if you can, with every response to your client, help them to make the next state transition using links and forms (these allow the client to update their own state, and to update application state).
For more reading there's a great example of RESTful interaction described here:
http://www.infoq.com/articles/webber-rest-workflow
This coffee shop example is refined and expanded upon in Jim Webber and Ian Robinson's book 'REST in Practice'.
Of course it may also be worth re-reading Fielding (section 5.2 most relevant I think):
http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm
Hard to explain in one post (sorry for the length!) but I hope this helps.
Personally, i'd prefer to have a url like mysite.com/dog/1/tell, and pass it command=2 and reward=3 via POST. Perhaps the dog ID could be in the data too.
Several reasons:
Actions that have consequences should not be done via GET, but having the whole request in the URL makes GET very tempting.
REST only says that the request should contain everything needed to perform the action, not that the URL should. Considering #1, i'd even say stuffing everything into a gettable URL is a bad idea.
Makes it a lot more versatile; an HTML form posting at the URL would be enough to test it.
As mentioned by someone else, URLs are intended to form a hierarchical namespace. You break that when you put your params in the URL, as (1) there's no clear parent/child relationship between, say, 'command' and 'reward', and (2) if none of the params are optional, it makes for a lot of invalid URLs. Naming the params makes it even worse, as now the same "resource" has 6 different and identically-functioning URLs...and that's if your framework actually supports doing that.
For a website i would say having the connecting words are useful, for an api, i'd say not really, good documentation is all that is required for an api.
mysite.com/tell/dog/1/command/2/reward/3
looks very much like
mysite.com/tell?dog=1&command=2&reward=3.
In the second case, order is definitely not important. Most probably, it's not important in the first case, either. If I were you, I'd accept any combination, because it's clearly not hierarchical as URLs are expected to be. Moreover, you can't expect mysite.com/tell/dog/1 do something useful.
Since dog id, command id, and reward id only make sense together, I'd state this fact, setting the order, too:
mysite.com/tell/dog-a-command-rewarding-by/1/2/3
or even
mysite.com/tell/dog-a-command-rewarding-by/1-2-3
because you can't expect mysite.com/tell/dog-a-command-rewarding-by/1 do something useful, too.