I am struggling with a design aspect of my restful api for templating collections of resources.
The endpoint calls for a json with the name to a particular template and a collections of tokens. The API will then create entries into numerous tables and use the tokens where appropriate.
A very simple example is:
*{
'template': 'DeviceTemplate'
'tokens': [
'customer': 1234,
'serial_number': '12312RF3242a',
'ip_address': '1.1.1.1'
]
}*
This creates a new device for the customer with that ip address along with several other objects, for instance interfaces, device users etc etc. I use the tokens in various places where needed.
I'm not sure how to make this endpoint restful.
The endpoint for /device is already taken if you want to create this resource individually. The endpoint I need is for creating everything via the template.
I want to reserve the POST /template endpoint for creating the actual template itself and not for implementing it with the tokens to create the various objects.
I want to know how to call the endpoint without using a verbs.
I also want to know if its a good idea to structure a POST with a nested JSON.
I'd suggest that you create an action on the template object itself. So right now if you do /templates/<id> you are given an object. You should include in that object a url endpoint for instantiating an instance of that template. Github follows a scheme that I like a lot [1] where within an object there will be a key pointing to another url with a suffix _url. So for instance, your response could be something like:
{
"template": "DeviceTemplate",
"id": "127",
...
"create_url": "https://yourdomain.com/templates/127/create",
...
}
Then this way you treat a POST to that endpoint the same as if this template (DeviceTemplate) was its own resource.
The way to conceptualize this is you're calling a method on an object instead of calling a function.
[1] - For example https://developer.github.com/v3/#failed-login-limit
Related
I have an entity Temperature.
My URLs are designed as follows:
GET /api/temperatures/new
GET /api/temperatures/{id}/edit
GET /api/temperatures
POST /api/temperatures
PUT /api/temperatures/{id}
DELETE /api/monitoring/temperatures/{id}
I would like to create multiple temperatures (a collection of temperatures) at once - are there any conventions in terms of the urls to use?
So far, I came up with the following:
POST /api/monitoring/temperatures/collection
GET /api/monitoring/temperatures/cnew
I thought there must be a convention for this already so would like to check with you.
GET /api/temperatures # Getting all resources
POST /api/temperatures # Create new resource
GET /api/temperatures/<id> # Get a single resource
PUT /api/temperatures/<id> # Edit all fields
PATCH /api/temperatures/<id> # Edit some fields
DELETE /api/temperatures/<id> # Delete a resource
These are the kinds of URL's Fielding describes in his thesis on REST. You shouldn't be describing what an end point does in the URL especially when used properly the HTTP verbs provide plenty of information. Be aware the REST architectural style has more to it than JSON over HTTP. Generic connectors, decoupling of components and a stateless server are key components of a RESTful application.
Note: Most people probably wouldn't implement both PUT and PATCH. PUT will be fine but I included it for completeness.
In response to your comment, if you are referring to creating multiple resources with one POST request you don't need a new URL. Your application should be able to handle {temp: 45, date: ...} and [{temp: 45, date: ...}, {temp: 50, date: ...}] at the same endpoint.
The HTTP method GET is not suitable for creating or editing resources - /api/temperatures/new and /api/temperatures/{id}/edit. HTTP GET is used for getting information without changing state in a server. You should use POST or PUT.
If you want to create multiple temperatures, you should use
POST /api/monitoring/temperatures
and consume JSON or XML list of objects.
Java example:
#POST
#Path("/temperatures")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Response postTemperatures(Temperatures temperatures){
// process and save
}
#XmlRootElement
public class Temperatures {
public List<Temperature> temperatures;
Temperatures(){}
}
You can update multiple entries with a single post by sending in an array of temperatures instead of a single entry,
POST /api/temperatures { [{...},{...}] }
but your api endpoint structure could be streamlined a little.
Ideally you want a simple consistent interface for all API resources.
I would personally simplify:
GET /api/temperatures/new
GET /api/temperatures/{id}/edit
GET /api/temperatures
POST /api/temperatures
PUT /api/temperatures/{id}
DELETE /api/monitoring/temperatures/{id}
to
GET /api/temperatures // Get all temperatures
POST /api/temperatures // Send in array of new entries to update
GET /api/temperatures/{id} // Read a specific temperature
PUT /api/temperatures/{id} // Update a specific temperature
DELETE /api/temperatures/{id} // Delete a specific temperature
This gives a consistent interface to the api for all temperature related calls that maps onto a CRUD interface.
Without context its hard to work out exactly what /api/temperatures/new is used for, but I would consider using a parameter on the call for finegraining the response.
e.g.
/api/temperatures?age=new // Get new temps
Which will allow you to use the common structure to add different types of criteria later on.
I'm currently working on a REST API, trying to design it with most best practices as possible.
I work with Symfony2 PHP framework but some of my questions are valid for any REST API i guess.
Starting from the base design for a particular resource :
GET /resource - Get all resources
POST /resource - Create resource
GET /resource/{id} - Get resource with id={id}
PUT|PATCH /resource/{id} - Edit the resource with id={id}
DELETE /resource/{id} - Delete the resource with id={id}
Supposing my resource has complex rules while updating.
It has a "status" field, (a float for example), that can be updated only by following a particular scheme
It has a "schedule" field (a datetime), with different choices available that are not always the same
How am I supposed to expose those rules to the API consumer ? For the schedule field, how am I supposed to provide the different choices available at the current time ?
About the Symfony server-side part, I followed most of the recommandations of this walkthrough : http://williamdurand.fr/2012/08/02/rest-apis-with-symfony2-the-right-way/
My POST, PUT & PATCH actions are handled with Symfony Forms, so most of the rules are processed by Symfony constraints/validations features.
But form binding is quite limited, let's supposed I want to trigger a particular event if the user change the status field from 2 to 3? What is the best way to do that ?
Thanks in advance.
HTTP has another verb you aren't using: OPTIONS. You can use this to list the schedule options.
Here's a blog article about it: http://zacstewart.com/2012/04/14/http-options-method.html
As for updating the status, I would reuse POST and include an action in the field. Example:
POST
{
"type": "update",
"status": 3
}
Modified REST:
GET /resource - Get all resources
POST /resource - Create resource
GET /resource/{id} - Get resource with id={id}
PUT|PATCH /resource/{id} - Edit the resource with id={id}
DELETE /resource/{id} - Delete the resource with id={id}
OPTIONS /resource/{id} - Retrieve options of resource with id={id}
Keep in mind that you can pass params along in the body for everything but GET and you can pass any params in the URL for GET.
I have zero knowledge on Symfony2, so I'll just concentrate on your more generic REST how-to qustion about exposing rules.
Give the consumers of your REST API a documentation. It's the first thing they will hit before actually playing with your API. Use tools for that, from auto-generated help pages to 3'rd party providers like Apiary.io or alike.
Create meaningful responses when consumers send "wrong" requests: use correct http response status codes (Bad request, Conflict, etc.) when request parameters are missing or invalid.
If your REST api is relaxed, it can also include information about what went wrong and how to resolve the problem in the response body.
What worked well for me in the past was to have a generic ErrorMessage entity that was returned upon each non-successful request, containing a title, an error description, and a dedicated more technical "dev-description" which can be enabled/disabled for test/production on the server side.
In my case, my consumers all know that they can get either the expected response entity in case of success, or that generic ErrorMessage entity in the response in case of failure.
If you can desribe your rules, why not provide those as meta information for your service? Eg. in my case I know I have a set of parameters, each having a set of available options. Think of the parameters as the key in a query string, and the options as the values for that key. In a complex world, parameter options depend on other parameter options, eg. in my case the available options for parameter B are dependent of what option(s) are "selected" for parameter A. I can expose those dependencies by providing a "metadata" resource in my REST api, eg. a JSON stucture listing all parameters and all options for those parameters, and for each option adding a "requires" section desribing that that option is only "available" if parameter xy has selected option p and q.
This allows my consumers to - with a single request to that meta data resource - create a "state-machine" on the client side. I hope you get the picture.
Here is my understanding of REST-full way to handle updates and advertise update operations to API client.
This is based on this wonderful book and Fowler's article about REST with some additions of File Levels of Media Type and article about Restfull CQRS. Basically you use PUT for update and pass the operation via content type and advertise content type via mediaType in hypermedia controls.
All operations which are available for current state of your resource are listed among hypermedia controls which are passed with representation of resource like this:
<myresource>
<status>ACTIVE</status>
<some-field with-attribute="value"/>
<some-other-field/>
<!-- other fields representing state of resource -->
<link rel = "self"
uri = "/resource/1234"/>
<link rel = "/linkrels/resource/changeStatus"
uri = "/resource/1234"
mediaType = "application/vnd.myapp+xml;domain-model=ChangeStatusCommand"/>
<link rel = "/linkrels/resource/changeSchedule"
uri = "/resource/1234"
mediaType = "application/vnd.myapp+xml;domain-model=ChangeScheduleCommand"/>
<link rel = "/linkrels/help"
uri = "/help/resource"/>
</myresource>
Links together with mediaType gives enough information what command is allowed. In many cases this should be something very specific to current state of resource. For example if you can move it from status ACTIVE to TRASHED than command should be named not StatusChange but TrashCommand and so on.
Suppose I have a RESTful API for managing orders which uses HAL to facilitate HATEOAS:
GET /orders/2
{
"_links": {
"self": "/orders/2",
"items": "/orders/2/items"
},
"subtotal": 30.0,
"shipped": false
}
I want to write my client (application) using a set of interfaces so that, assuming that implementations of these interfaces are DI-d/built by DI-d factories, etc., I don't really (want to) have to care that they're backed by my RESTful API. As an example (pseudo C#/Java):
public interface Order {
public void addItem(Item item);
public float getSubtotal();
public boolean getShipped();
}
Order order = ...;
Item item = ...;
order.addItem(item);
...(order.getSubtotal())...;
My question is: can I/does it make sense to generate implementations of the Order/Item interface from the API? By this I mean in a manner similar to that offered with C#/web services which export WSDLs.
I've been thinking about implementing OPTIONS for resources such as /orders and /orders/{id} so that I'd effectively have a HATEOAS API for traversing the schema of the API:
GET /orders/* (I'd need a suitable wildcard of course)
{
"_links": {
"addItem": {
"href": "/orders/{id}/items",
"templated": true,
"type": "method"
}
}
}
Of course I could make this part of the _links object returned with any given resource (/orders/2, for instance) but that precludes static code generation.
I'm wondering if there's a sensible way to encapsulate the fact that if a particular link is provided, the related action should be available/performed, otherwise not.
Note: In case it matters, I'm actually working in JavaScript (specifically with AngularJS). However, I'd still like to write my application using a set of conceptual interfaces/contracts.
My question is: can I/does it make sense to generate implementations
of the Order/Item interface from the API? By this I mean in a manner
similar to that offered with C#/web services which export WSDLs.
It partially makes sense. By a simple CRUD API you can map the resources to the entities. By complex applications it does not work, because you map URIs to resources and METHOD URI pairs to operations. So every time if you need an operation not defined by HTTP, you have to create a new resource or at least a new URI for an already existing resource.
Some examples:
transfer money from one account to another: POST /transfer [acc1, acc2, amount, currency] - the transfer does not necessary exist as an entity in your domain logic (don't try that kind of solution in production code unless you want bankruptcy :D)
sending an email to another user: POST /messages [recipient, message]
you can map resources to value objects too: GET /users/123/address
you can use URIs to map reduce a collection: GET /users?name="John"
you can use PUT /users/123 [details] instead of POST /users [details] to create a new user
you can use POST /player/123/xp/increment 10 instead of PUT /player/123/xp [xp+10] to update the experience points of a player
About the WSDL like solutions you can read alot more here: Third Generation Web APIs - Markus Lanthaler.
My personal opinion that it does not worth the effort to build such a system, because it has more drawbacks than advantages.
How to I represent a complex resource for a REST post?
Hello,
Currently I have an application which when the user hits "save" it iterates over all of the form elements and creates one mass object which manages a:
var = params = [{
attributes1: form1.getValues(),
attributes2: form2.getValues(),
.. ..
}];
I then send this mass object via a RPC POST to my "Entity" model service.
This entity which I wish to persist data for is quite complex. All in all, the data is spread accross about 30 tables. To help explain my actual question, the "entity" is a building (as in a physical property/house/apartment).
What I would like, is to be able to turn my mess into a RESTful API for saving properties.
The problem I have is that, saving details for a single model that spans a single table is fine. How do I structure my data object for transport when the model has
many to many relationships
one to many relationships
one to one relationships
For example:
Here is a WATERED down version of what I might have on a property and the sample data
propertyId: 1,
locationId: 231234,
propertyName: "Brentwood",
kitchenFeatures: [
{ featureId: 1, details: "Induction hob"},
{ featureId:23, details: "900W microwave"}
],
propertyThemes: [ 12,32,54,65 ]
This actually goes on a lot more.. but you can get the general gist. kitchenFeatures would be an example of a many-to-many, where I have a featuresTable which has all of the features like so:
`featureId`, `feature`
1 "Oven Hob"
23 "Microwave"
and propertyThemes would be an example of another many-to-many.
How am I expected to form my "object" to my RESTful service? Is this even possible?
ie. If I want to save this property I would send it to:
http://example.com/api/property/1
The approach I would use here is hypermedia and links:
/property
/property/{id}
/property/{id}/features/{id}
Depending on your domain you might even get away with:
/property/{id}/features/{name}
or
/property/{id}/features/byname/{name}
Thus you can do REST operations and serve JSON or XHTML hypermedia.
Property details:
Request: GET /property/1
Response:
{
..
"name": "Brentwood",
"features": "/property/1/features"
..
}
Brentwood's features:
GET /property/1/features
{
..
"Kitchen": "/property/1/features/1",
"Dog Room": "/property/1/features/dog%20room",
..
}
GET /property/1/features/1
{
..
"Induction hob": "/property/1/features/1/1",
"900W microwave": "/property/1/features/1/23",
"nav-next" : "/property/1/features/dog%20room",
..
}
To add a relation you can do something like this:
POST /property/1/features
{
..
"Name": "Oven Hob"
..
}
If you know what the relation will be you use a PUT:
PUT /property/1/features/23
{
..
"Name": "Oven Hob"
..
}
You can serve multiple media types:
GET http://host/property/1/features/dog%20room.json
GET http://host/property/1/features/dog%20room.xhtml
For the response in xhtml the response can use named links like this:
..
Kitchen
..
There are other aspects of REST that you can use such as response code which I did not include above.
Thus, to model relations you make use of links which can be in itself a resource that can be operated on with GET, PUT, POST and DELETE or even custom verbs such as ASSOCIATE or LINK. But the first four are the ones that people are used to. Remember PUT is idempotent but not POST. See PUT vs POST in REST
Edit: You can group your links into JSON arrays to give structure to your hypermedia.
I think you're really asking, "How do I represent complex data in a form suitable for transmission within a POST?", right? It's less to do with REST and more to do with your choice of media type. I would suggest starting with a pure JSON representation, using arrays and cross-referenced ID fields to map the relationships. You could also do this with XML, of course.
The examples you gave look right on the money. You just need to ensure that both parties (browser and server) agree on the structure and interpretation of the media type you use.
I'm dealing with the exact same thing. I opted to not use id's anywhere, but use urls everywhere an id would normally be expected.
So in your case, the kitchenfeatures could simply be an array with urls to:
/feature/1
/feature/23
And the themes to
/propertyTheme/12
/propertyTheme/32
etc..
In the case of many-to-many relationships, we update all the relations as a whole. Usually we simply dump the existing data, and insert the new relationships.
For one to many relationships we sometimes extend the urls a bit where this makes sense. If you were to have comments functionality on a 'property', this could look like
/property/1/comment/5
But this really depends on the situation for us, for other cases we put it in the top-level namespace.
Is this helpful to you?
I am writing a RESTful service for a customer management system and I am trying to find the best practice for updating records partially. For example, I want the caller to be able to read the full record with a GET request. But for updating it only certain operations on the record are allowed, like change the status from ENABLED to DISABLED. (I have more complex scenarios than this)
I don't want the caller to submit the entire record with just the updated field for security reasons (it also feels like overkill).
Is there a recommended way of constructing the URIs? When reading the REST books RPC style calls seem to be frowned upon.
If the following call returns the full customer record for the customer with the id 123
GET /customer/123
<customer>
{lots of attributes}
<status>ENABLED</status>
{even more attributes}
</customer>
how should I update the status?
POST /customer/123/status
<status>DISABLED</status>
POST /customer/123/changeStatus
DISABLED
...
Update: To augment the question. How does one incorporate 'business logic calls' into a REST api? Is there an agreed way of doing this? Not all of the methods are CRUD by nature. Some are more complex, like 'sendEmailToCustomer(123)', 'mergeCustomers(123, 456)', 'countCustomers()'
POST /customer/123?cmd=sendEmail
POST /cmd/sendEmail?customerId=123
GET /customer/count
You basically have two options:
Use PATCH (but note that you have to define your own media type that specifies what will happen exactly)
Use POST to a sub resource and return 303 See Other with the Location header pointing to the main resource. The intention of the 303 is to tell the client: "I have performed your POST and the effect was that some other resource was updated. See Location header for which resource that was." POST/303 is intended for iterative additions to a resources to build up the state of some main resource and it is a perfect fit for partial updates.
You should use POST for partial updates.
To update fields for customer 123, make a POST to /customer/123.
If you want to update just the status, you could also PUT to /customer/123/status.
Generally, GET requests should not have any side effects, and PUT is for writing/replacing the entire resource.
This follows directly from HTTP, as seen here: http://en.wikipedia.org/wiki/HTTP_PUT#Request_methods
You should use PATCH for partial updates - either using json-patch documents (see https://datatracker.ietf.org/doc/html/draft-ietf-appsawg-json-patch-08 or http://www.mnot.net/blog/2012/09/05/patch) or the XML patch framework (see https://www.rfc-editor.org/rfc/rfc5261). In my opinion though, json-patch is the best fit for your kind of business data.
PATCH with JSON/XML patch documents has very strait forward semantics for partial updates. If you start using POST, with modified copies of the original document, for partial updates you soon run into problems where you want missing values (or, rather, null values) to represent either "ignore this property" or "set this property to the empty value" - and that leads down a rabbit hole of hacked solutions that in the end will result in your own kind of patch format.
You can find a more in-depth answer here: http://soabits.blogspot.dk/2013/01/http-put-patch-or-post-partial-updates.html.
I am running into a similar problem. PUT on a sub-resource seems to work when you want to update only a single field. However, sometimes you want to update a bunch of things: Think of a web form representing the resource with option to change some entries. The user's submission of form should not result in a multiple PUTs.
Here are two solution that I can think of:
do a PUT with the entire resource. On the server-side, define the semantics that a PUT with the entire resource ignores all the values that haven't changed.
do a PUT with a partial resource. On the server-side, define the semantics of this to be a merge.
2 is just a bandwidth-optimization of 1. Sometimes 1 is the only option if the resource defines some fields are required fields (think proto buffers).
The problem with both these approaches is how to clear a field. You will have to define a special null value (especially for proto buffers since null values are not defined for proto buffers) that will cause clearing of the field.
Comments?
RFC 7396: JSON Merge Patch (published four years after the question was posted) describes the best practices for a PATCH in terms of the format and processing rules.
In a nutshell, you submit an HTTP PATCH to a target resource with the application/merge-patch+json MIME media type and a body representing only the parts that you want to be changed/added/removed and then follow the below processing rules.
Rules:
If the provided merge patch contains members that do not appear within the target, those members are added.
If the target does contain the member, the value is replaced.
Null values in the merge patch are given special meaning to indicate the removal of existing values in the target.
Example test cases that illustrate the rules above (as seen in the appendix of that RFC):
ORIGINAL PATCH RESULT
--------------------------------------------
{"a":"b"} {"a":"c"} {"a":"c"}
{"a":"b"} {"b":"c"} {"a":"b",
"b":"c"}
{"a":"b"} {"a":null} {}
{"a":"b", {"a":null} {"b":"c"}
"b":"c"}
{"a":["b"]} {"a":"c"} {"a":"c"}
{"a":"c"} {"a":["b"]} {"a":["b"]}
{"a": { {"a": { {"a": {
"b": "c"} "b": "d", "b": "d"
} "c": null} }
} }
{"a": [ {"a": [1]} {"a": [1]}
{"b":"c"}
]
}
["a","b"] ["c","d"] ["c","d"]
{"a":"b"} ["c"] ["c"]
{"a":"foo"} null null
{"a":"foo"} "bar" "bar"
{"e":null} {"a":1} {"e":null,
"a":1}
[1,2] {"a":"b", {"a":"b"}
"c":null}
{} {"a": {"a":
{"bb": {"bb":
{"ccc": {}}}
null}}}
For modifying the status I think a RESTful approach is to use a logical sub-resource which describes the status of the resources. This IMO is pretty useful and clean when you have a reduced set of statuses. It makes your API more expressive without forcing the existing operations for your customer resource.
Example:
POST /customer/active <-- Providing entity in the body a new customer
{
... // attributes here except status
}
The POST service should return the newly created customer with the id:
{
id:123,
... // the other fields here
}
The GET for the created resource would use the resource location:
GET /customer/123/active
A GET /customer/123/inactive should return 404
For the PUT operation, without providing a Json entity it will just update the status
PUT /customer/123/inactive <-- Deactivating an existing customer
Providing an entity will allow you to update the contents of the customer and update the status at the same time.
PUT /customer/123/inactive
{
... // entity fields here except id and status
}
You are creating a conceptual sub-resource for your customer resource. It is also consistent with Roy Fielding's 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..." In this case the conceptual mapping is active-customer to customer with status=ACTIVE.
Read operation:
GET /customer/123/active
GET /customer/123/inactive
If you make those calls one right after the other one of them must return status 404, the successful output may not include the status as it is implicit. Of course you can still use GET /customer/123?status=ACTIVE|INACTIVE to query the customer resource directly.
The DELETE operation is interesting as the semantics can be confusing. But you have the option of not publishing that operation for this conceptual resource, or use it in accordance with your business logic.
DELETE /customer/123/active
That one can take your customer to a DELETED/DISABLED status or to the opposite status (ACTIVE/INACTIVE).
Things to add to your augmented question. I think you can often perfectly design more complicated business actions. But you have to give away the method/procedure style of thinking and think more in resources and verbs.
mail sendings
POST /customers/123/mails
payload:
{from: x#x.com, subject: "foo", to: y#y.com}
The implementation of this resource + POST would then send out the mail. if necessary you could then offer something like /customer/123/outbox and then offer resource links to /customer/mails/{mailId}.
customer count
You could handle it like a search resource (including search metadata with paging and num-found info, which gives you the count of customers).
GET /customers
response payload:
{numFound: 1234, paging: {self:..., next:..., previous:...} customer: { ...} ....}
Use PUT for updating incomplete/partial resource.
You can accept jObject as parameter and parse its value to update the resource.
Below is the Java function which you can use as a reference :
public IHttpActionResult Put(int id, JObject partialObject) {
Dictionary < string, string > dictionaryObject = new Dictionary < string, string > ();
foreach(JProperty property in json.Properties()) {
dictionaryObject.Add(property.Name.ToString(), property.Value.ToString());
}
int id = Convert.ToInt32(dictionaryObject["id"]);
DateTime startTime = Convert.ToDateTime(orderInsert["AppointmentDateTime"]);
Boolean isGroup = Convert.ToBoolean(dictionaryObject["IsGroup"]);
//Call function to update resource
update(id, startTime, isGroup);
return Ok(appointmentModelList);
}
Check out http://www.odata.org/
It defines the MERGE method, so in your case it would be something like this:
MERGE /customer/123
<customer>
<status>DISABLED</status>
</customer>
Only the status property is updated and the other values are preserved.
Regarding your Update.
The concept of CRUD I believe has caused some confusion regarding API design. CRUD is a general low level concept for basic operations to perform on data, and HTTP verbs are just request methods (created 21 years ago) that may or may not map to a CRUD operation. In fact, try to find the presence of the CRUD acronym in the HTTP 1.0/1.1 specification.
A very well explained guide that applies a pragmatic convention can be found in the Google cloud platform API documentation. It describes the concepts behind the creation of a resource based API, one that emphasizes a big amount of resources over operations, and includes the use cases that you are describing. Although is a just a convention design for their product, I think it makes a lot of sense.
The base concept here (and one that produces a lot of confusion) is the mapping between "methods" and HTTP verbs. One thing is to define what "operations" (methods) your API will do over which types of resources (for example, get a list of customers, or send an email), and another are the HTTP verbs. There must be a definition of both, the methods and the verbs that you plan to use and a mapping between them.
It also says that, when an operation does not map exactly with a standard method (List, Get, Create, Update, Delete in this case), one may use "Custom methods", like BatchGet, which retrieves several objects based on several object id input, or SendEmail.
It doesn't matter. In terms of REST, you can't do a GET, because it's not cacheable, but it doesn't matter if you use POST or PATCH or PUT or whatever, and it doesn't matter what the URL looks like. If you're doing REST, what matters is that when you get a representation of your resource from the server, that representation is able give the client state transition options.
If your GET response had state transitions, the client just needs to know how to read them, and the server can change them if needed. Here an update is done using POST, but if it was changed to PATCH, or if the URL changes, the client still knows how to make an update:
{
"customer" :
{
},
"operations":
[
"update" :
{
"method": "POST",
"href": "https://server/customer/123/"
}]
}
You could go as far as to list required/optional parameters for the client to give back to you. It depends on the application.
As far as business operations, that might be a different resource linked to from the customer resource. If you want to send an email to the customer, maybe that service is it's own resource that you can POST to, so you might include the following operation in the customer resource:
"email":
{
"method": "POST",
"href": "http://server/emailservice/send?customer=1234"
}
Some good videos, and example of the presenter's REST architecture are these. Stormpath only uses GET/POST/DELETE, which is fine since REST has nothing to do with what operations you use or how URLs should look (except GETs should be cacheable):
https://www.youtube.com/watch?v=pspy1H6A3FM,
https://www.youtube.com/watch?v=5WXYw4J4QOU,
http://docs.stormpath.com/rest/quickstart/