URIs identify resources and are treated as nouns for this purpose, but that doesn't mean that a verb cannot be used as a noun. (2NS)
For example, the verb-as-a-resource could be some long lived business process, identified by an URL such as http://mycompany.com/hr/terminateEmployee/234346. In this case, GET would mean "show a representation of the state of the termination process of employee #234346". (2NT)
Agreed. Any interesting verb is identical to any interesting noun. (2NU)
JB: note that a more RESTful model of this might be http://mycompany.com/hr/Employee/234346/Termination (2NW)
Anon: Yes, that is a better name, but I wouldn't call that more RESTful. REST doesn't say anything about good or bad practice in name creation. You can have bad names and still be RESTful - you'll just have more issues changing names in the future. REST does help with that at least, through redirection like HTTP's 3xx response codes. (2NX)
JB: actually, I think I disagree somewhat. ;) Though we're nowhere near being able to really make the argument precisely, I think REST encompasses a philosophy for modeling problem domains; the issue isn't really names, it's a question of what the appropriate model objects are for a given domain. One guiding principle is to ask "does it make sense to GET / PUT / POST to this named resource?" Each component of the URI should be a resource for which these operations make sense. In the first example above, .../terminateEmployee is an odd thing to model; what does it mean to GET / PUT / POST this resource? (2NY)
Well, that's my point, that the resource identifies the 'process' of terminating an employee. i.e. the noun, not the verb. Doing a GET on it might return "The employee has been given their notice, and their last day is 2001/mm/dd". (2NZ)
>> There may be a disconnect here. The author in roman above points out that the URI with terminateEmployee before 234346 raises a question. This is in contrast to the URI with 234346 before terminateEmployee, which does not raise that particular question. The author in italics may have missed that: the URI with terminateEmployee first, when ended with the terminateEmployee component, does not identify any employee. So a GET on that URI, which returned "The employee ... " would not be a happy get, since there is no employee identified by that URI. -- JoaquinMiller (2O0)
SteveSexton: Does this become more clear if you focus on the state of the employee, rather than the process of changing the state ? For example, http://mycompany.com/hr/Employee/234346/EmploymentStatus. You would terminate the employee (which seems to be the thrust of the original example) by PUTting a document that indicated a new status of "Terminated" and perhaps with an effective date. Did I just effectively counter the argument "Verbs can be Nouns" ? I hope not... there are probably scenarios in which a verb makes sense instead of a noun, but I'm at a loss to come up with one. (2O1)
Winter: I can't think of a reason why it would ever be necessary to use a verb as a resource. While I agree with JB that the name per se isn't that important, using a name to identify a process seems more RPC-like than REST-like. In the case above, calling a "terminateEmployee" URI via a GET, if it actually triggered the empolyee's termination would violate the no side effect principle of the GET method. (2O2)
It would be more RESTful to POST or PUT to a specific resource (depending on the semantics of the situation), for example: (2O3)
1. Use a POST to a general "terminator" resource (e.g., "http://mycompany.com/hr/terminator") or perhaps an employee-specific terminator (e.g., "http://mycompany.com/hr/employeeTerminator") and provide the details of who is to be terminated: (2O4)
POST /hr/terminator HTTP/1.1 Host: mycompany.com <employee id="234346"/> (2O5)
2. Use a PUT to the employee itself: (2O6)
PUT /hr/employee/234346 HTTP/1.1 Host: mycompany.com <employee> <terminated>true</terminated> </employee> (2O7)
Using a name to identify a process is RPC-like; using a name to identify a processor is REST-like. The difference is important, since a processor could conceivably have it's own state. (2O8)
For example, the "terminator" in this case is an actual resource whose state itself could conceivably be queried with a GET (perhaps returning a document that shows which types of employees it's able to terminate; where it forwards employee info after the fact; etc.) and updated with a PUT. (2O9)
You don't need to posit the existence of a 'terminator' processor in order to collect state. There may exist no such termination agent, no such permissions, etc., and yet there is still state in and around the description of a termination of an employee. All I have to do is publish my plan to terminate your employment (no matter where you work, no matter my position) and I have created a resource you can GET, PUT, POST, DELETE to your heart's content. (2OA)
When I publish my evil intent this way, I am not converting verbs into nouns or any such thing as that. I am merely using the age-old trick of materialization through description. If it can be thought of, it's a resource. Unless of course the artist lacks the skill to convert imagination into representation. For that, REST won't help. (2OB)
That said, my belief and my preference is to avoid materializing processes when object state can be addressed more directly. Ultimately, it comes down to a question of how much state needs to be exposed to clients. If clients need to be able to follow the workflow of an employment termination, then we need to materialize that process through a plan and a status. If not, why not just POST the <pink-slip/> directly to the employee resource? (2OC)
Although HTTP 1.1 condones the notion of "processor" resources, i.e., resources to which you can submit a form and receive back a response, but yet the resource seems to support no intrinsic state itself, I believe that part of the spec is broken. The problem is not that a resource has no state (or only trivial state), but rather that other resources are being addressed through the exchange of request and response data, but are not properly identified. This is the "hole" from which all tunnels are built. (2OD)
The "processor resource" abstraction is less desirable than the "resource with subordinate resources" abstraction, for the above reason, and all cases of the former ought to be forced into the mould of the latter, IMO. If this cannot be done, then you have a design misfit, and it's back to the drawing board. (2OE)
-- WaldenMathews (http://ilx.com/employee/329) (2OF)
''ok, what does POST or PUT? will it deliver mournings to a terminated employee? ;) (2OG)
the last example does not really work because it does not have ANY CONTEXT. who is getting the resource? executive manager, hr administrator or buddy from the delivery department. see my point? sure, the method is GET but it require "damned" parametrization. (2OH)
the "rest" is the architecture based on addressing rather than parametrization (as in soap etc.) the real problem is that, - "there are two kinds of people in the world" ones who apply few actions to multiple things (a.k.a rest) and others who apply specific action to particular things (a.k.a. soap and xml-rpc). of course, everything that others do seems inefficient and complex for those who think strait and simple :) (2OI)
btw: could somebody tell me how "restful" get-post-put (g-p-p for short ;) ) will look for application that need to compare two somehow "identical" resources: "john smith - the doctor" and "john smith - the janitor" and both employees had have been terminated during sequels of layoffs. it seems to me that comparison in the "rest" achitecture is the task of the client software, isn't it? (2OJ)
i've been reading everything possible about "rest". and i did not find the reason why "rest" addressable resources should replace procedural methods or why it is better and more "scalable". it seems that there are applications for one as well as applications for another. the "rest" seems good for data retrieval or access and the "dishwasher" (a.k.a soap :) ) is good for data processing... (2OK)
ok, enough, - it surely become a "kitchen"... (2OL)
sincerely, (2OM)
- igor bazdyrev <bigor@pacbell.net> (2ON)
ps: in my work i'm using "rest"-like addressing to refer resources within huge pile of enterprise documents and database records, but the complex workflow automation is implemented using xml-rpc messaging... and it works... user is able to locate resource and to route it as necessary... to the cell phone or fax or data "grinder" that creates new resources using some elements or references to the original... (2OO)
I suggest that URI that point to resources accepting POST MAY be verbs and URI that point to resources taking GET/PUT/DELETE SHOULD be nouns. (2OP)
Say I have a resource "http://www.example.com/wikidoc.txt" I can GET or PUT this resource formated as reST (reStructuredText). For browsing pleasure I want this resource in html, only there exist no such representation. (2OQ)
We can expose a transformer in the URI space and create represntations dynamicly. A POST to "http://www.example2.com/htmltransform" with a link to the src would create a representation and return "201 Created" and a "Location: http://www.example2.com/www.example.com/wikidoc.txt.html". (2OR)
If I would want the transformer respond to GET (with, say, a usage description) however it would make more sense to name it "http://www.example2.com/htmltransformer". (2OS)
Note: It would be cool if a PUT could be used for creating such a resource, it's kind of a named pipe. (2OT)
- JohnNilsson <john@milsson.nu> (2OU)
Why don't you just do a DELETE to http://mycompany.com/hr/Employee/234346 (364)
[ JoshSled ]: Depends on what you're trying to do... if you really screwed up and there's no actual such employee [book fell on the keyboard and hit submit], then that's probably the right thing. But for a variety of reasons [legal -- still have payroll taxes for them, practical -- they're going to come by next week to finish up some paperwork, &c] it's probably not correct to delete the Employee resource from the HR system. And if it's not being deleted, then DELETE probably isn't the right verb. (36M)
1. If your system has a termination process available, then I would have thought that GETting http://mycompany.com/hr/Employee/234346 would show something like... (6GQ)
Employee 234346 Status: employed Section: http://mycompany.com/ict Role: http://mycompany.com/ict/web/nerd Manager: http://mycompany.com/hr/Employee/234340 (6H4)
...and GETting http://mycompany.com/hr/Employee/status would show ... (6GU)
employed | terminated | termination-in-progress | hiring-in-progress (6HL)
...and GETting http://mycompany.com/hr/Employee/status/terminated would show ... (6HM)
reason date (6HG)
...and GETting http://mycompany.com/hr/Employee/status/terminated/reason would show ... (6H7)
quit | deceased | fired | disappeared | redundant | retired (6HH)
...and GETting http://mycompany.com/hr/Employee/status/terminated/date would show (6H9)
now | [date in Internation Date Format/ISO 8601 Calendar date ] (6HI)
2. PUTting <status status='terminated' reason='quit' date='now'/> or <status status='termination-in-progress' reason='quit' date='now'/> to http://mycompany.com/hr/Employee/234346/status should initiate termination, so that susequent GETs http://mycompany.com/hr/Employee/234346/status would show... (6GX)
termination-in-progress : quit : 2009_07_31 (6HC)
...and - after termination finishes - GETting http://mycompany.com/hr/Employee/234346/status would show (6GZ)
terminated : quit : 2009_07_31 (6H1)
[Aside: It's an OR for the status in the PUT because the state machine goes hiring-in-progress -> employed -> termination-in-progress -> terminated; that is too simplistic to work in real life, but as a toy it means that the business logic can go "if employed and we want to make terminated, we have to go through termination-in-progress".] (6H2)
Sending the employee id to the “terminator” is *not* transferring a representation of the state of a resource, where as the GET/PUT to the employee is. (6OG)
If you wanted a terminator to do the terminations then you could POST to (6OE)
POST /hr/terminations HTTP/1.1 Host: mycompany.com <termination> .... </termination> (2O5)
Robert Wilson(wilsonrm@computer.org) (6OF)