POST
doesn't mean "create", it means "process". You can create a new resource by posting a suitable request to an existing resource (i.e. post to /customers
to create a new customer). But you can also use POST
to fill in all of the other actions which don't correspond to a neat CRUD paradigm.
In the case of printing, you should consider the act of printing as a resource itself. You're asking the system to create a "print job" for you. This means you can have a prints/
resource which acts as the container for all prints requested. When you want to print something you POST
a document to this resource which contains all the information about the print-out you want to create, identifying the resources you want to print with links to them.
As a JSON document, it could look like this:
{
contents: ["http://site/customers/12345"],
paper-size: "A4",
duplex: "true"
}
Obviously, you need to customise this to be relevant to what you want to do. The key thing is that you're identifying other resources to print by specifying their URL.
In response to the request, you could simply return a 200 OK
or a 204 No-Content
and treat it as a fire-and-forget process. However, if you wanted to enhance it, you could return 201 Created
and specify the URL of the newly created print job, e.g. /prints/12345
.
A user could then perform a GET
on the resource to see the status of their print job (pending, in-progress, etc), or could request the job be cancelled by issuing a DELETE
.
Once you rephrase the problem in terms of resource, the RESTful design should come naturally and give you opportunity to expand and enhance in ways you may not have immediately considered.
Best Answer
Standard URL mapping for REST has the resource mapped to the URL and what you do to it in the HTTP method.
It works well when interacting programmatically with your REST endpoint. It's also very discoverable and consistent: if you get a link to a resource, you know you can try other methods and - if supported - they'll behave in a standard CRUD pattern.
However, it can be somewhat inconvenient to debug from a browser, because they're not really design to do anything else than GET from the URL bar - so you need extra plugins (or use CURL/other tools).
Unfortunately, using the non standard mapping in the question (e.g. '/editUser/id') alone doesn't really solve that issue - you still need a body to go with the request, so I don't see how that makes it easier. Or lots of URL query parameters, but that breaks the symmetry between actions.
If by 'easier for others' your dev is meaning 'easier on people that try to access it from a basic browser for anything other than GET', then a way to do that would be to stick to the basic resource mapping but (optionally) stick the verb/method in a query parameter, e.g. /user/?action=DELETE. I'd still support the standard HTTP methods and make the above totally optional, not best practice, and for debugging/manual exploration only.