I'm converting a SOAP based RPC style "web service" to a JSON based REST web service using ASP.NET Web API. Methods such as AddXYZ / UpdateXYZ / RemoveXYZ map cleanly to the HTTP verbs for POST/PUT/DELETE. Are there any best practices/guidance for mapping typical RPC style operations such as "ExecuteXYZ" or "AssignXYZ" style methods to it's REST counterpart? My take is that such operations would map to corresponding URL addressable resources such as "ExecuteXYZRequest" and "AssignXYZRequest"
http://myhost/myservice/ExecuteXYZRequest
http://myhost/myservice/AssignXYZRequest
A request to execute "ExecuteXYZ" would then translate to a POST operation.
Getting the submitted request would translate to a GET(typically would be used to get the status of the submitted request).
http://myhost/myservice/ExecuteXYZRequest/1 <--- 1 is the ID of the request
Cancelling the request(assuming it's cancellable) would translate to a DELETE
POST would not really map to anything.
Does the above sound like a reasonable REST implementation or am I totally off in my thinking here? Thought/guidance much appreciated.
UPDATE Here is the specific example I'm trying to model: A many to many relationship between a Contact and an Event entity. What would be the best way to model the membership of a Contact to an Event as a REST resource such that a Contact can be added/ removed from an Event. In the RPC land This would be a method such as "AssignContactToEvent" which takes the IDs of both entities and set up the relationship between these two. How can this be modeled naturally in REST as a resource. I recall that there is a concept of links and "rel" but cannot find a concrete practical example illustrating how to model something like this using Web API
Question is whether it makes sense for the RPC methods to map to REST resources as indicated in the post
In a nutshell; no, it doesn't make sense to map methods to resources in the way you describe :)
In order to successfully "do REST" we have to think a little differently, and abandon all thoughts of RPC and CRUD-operations; these are really rather limiting once you embrace being RESTful!
The key abstraction of information in REST is a resource. Any information that can be named can be a resource: a document or image, a temporal service (e.g. "today's weather in Los Angeles"), a collection of other resources, a non-virtual object (e.g. a person), and so on. In other words, any concept that might be the target of an author's hypertext reference must fit within the definition of a resource. A resource is a conceptual mapping to a set of entities, not the entity that corresponds to the mapping at any particular point in time. http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm
A method or action/verb is then not a resource, so it has no place in a URI -- unless of course you're building an application that allows people to create their own methods, which would be rather unusual!
Taking your specific example for a contacts and events relationship, it's important to understand that your 'AssignContactToEvent' is an action that happens under the Web-API layer and cannot be modelled RESTfully; I hope this will become clear in the course of the following examples :)
First we need some good resources to model a list of all Contacts, and a list of all Events:
/contacts
/events
These resources model an individual Contact or Event identified by an ID-token:
/contacts/{contact_id}
/events/{event_id}
The users of your application want to know who is involved in a particular Event, so we need a resource that models a list of the Event's participants:
/events/{event_id}/participants
When we want to add a Contact to an Event, we could POST a minimal Contact-representation (containing just the Contact-ID) to the Event's participants-list:
POST /events/{event_id}/participants/ HTTP/1.1
Content-Type: application/json
{'id': {contact_id}}
To remove a Contact from an Event:
DELETE /events/{event_id}/participants/{contact_id} HTTP/1.1
Your application-users also want to see at-a-glance the Events a Contact is participating in, so you need another to resource to model this:
/contacts/{contact_id}/events
Similarly, you can now GET a list of Events for the Contact, and assign Events using POST:
POST /contacts/{contact_id}/events/ HTTP/1.1
Content-Type: application/json
{'id': {event_id}}
The important point to take onboard is that whenever you need to model something new, you create a resource. The details of how you store the properties and relationships of data-objects are abstracted away behind a Web-API. Indeed, the data-storage technology might change in future, say from relational to object-store, or you change your programming language or framework, but in all cases your URI's (and Web-API) remain the same. REST and HTTP are designed to endure well-beyond the technologies that run under-the-hood.
As a final example of creating new resources, consider a resource that models a list of Contact's who have an organiser-role:
/events/{event_id}/organisers
or this one that models the list of Events that a Contact is organising:
/contacts/{contact_id}/events-organised
If you have a authentication-system, then you might want to see the events you are attending:
/my-account/events
I hope this helps to clarify the purpose of a Web-API and following RESTful principles.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With