Rest – Represent actions(verbs) in REST URI

rest

I have a print operation to perform for my customer documents.
I need the other standard operations to be performed as well, like add,update, delete.
so, I have following:

  • For creating new customer:
    URI = /customer/{id}, type = POST,
    Methodname = CreateCustomer()
  • For updating:
    URI: /customer/{id}, type = PUT, method =
    UpdateCstomer()
  • For Delete customer:
    URI = /customer/{id}, type =
    DELETE, Methodname = DeleteCustomer()
  • For View:
    URI: /customer/{id}, type = GET, method = GetCustomer()

Now, if I need to print a document for that customer, I need a print function.
My URI may look like this: /customer/{id}, type = POST , method = PrintCustomer().
But I have used that URI and POST type for CreateCustomer.
I wanted the URI to look like this:
/customer/Print/{id}, type = POST , method = PrintCustomer().

But I cannot have "Print" verb in my URI. Whats the best way to do this?
I thought about /customer/document/{id} as the URI… but I will run into the same issue.
I would have the CRUD operations on the "document". So, again I run out of what I would used for "print".
Please advise.

Best Answer

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.