0

I'm implementing a RESTful API for what is essentially a document store, but am hitting a brick wall because I need a hybrid approach to one of the operations that can be performed on these documents.

Essentially, a user should be able to generate PDF versions of documents that are stored as JSON but also generate PDF versions of JSON strings that are passed arbitrarily (with no record in the database). The PDF reports never need to be stored anywhere, they are always generated on the fly.

My current API looks like:

/Documents
/Documents/1234
/Documents/1234?rev=4

Now, one way to implement the PDF generation would be to do:

/Documents/1234/Reports

or

/Reports/1234

But since we don't need to store PDFs (generated on the fly), both are reduced to only a GET operation, and it doesn't really act on a 'Report' object - which doesn't seem RESTful to me.

What complicates it further is that a user should be able to manually pass a JSON blob to the service and get a PDF. So something like:

/API/GeneratePDF

So does a separate stateless API make sense for this one operation? Maybe then redirect a request like /Reports/1234 to /API/GeneratePDF with the JSON blob for the 1234 document. It all seems a bit messy :)

Ming Chan
  • 1,938
  • 11
  • 21
Bharat
  • 463
  • 1
  • 8
  • 17
  • 1
    If you ever find yourself thinking "that doesn't seem RESTful" ask yourself which REST constraint is being violated. (BTW in this case, you are not violating any) – Darrel Miller Dec 31 '13 at 18:58

1 Answers1

1

The URL '/reports/123/' is pointing to a 'report' resource and it should not matter what backend operations will be acted on it.

When thinking about resource-url and its associated operations, the only relevant operations are "GET/PUT/POST/DELETE"

Then map the business operations (like generate PFD report) to the url+HTTP-Op+params.

Like in this case, map 'generate PDF report" to "GET /reports/123/"

use-case-1: simple get report

GET /reports/123/   
return: {pdf-report}

use-case-2: customized report

GET /reports/123/    
param: {"json info passed along with the get operation"
return: {pdf-report}

The the backend can detect if there are input from the client to decide what specific backend operations should be taken to generate the report.

Hope this help!

Ming Chan
  • 1,938
  • 11
  • 21
  • So this makes sense even when there isn't a 123 report right? As in, a user just wants to send some JSON and get a PDF of that (no saving anything). I guess it does, and a GET operation on /reports/ will do it. I guess I was confused because I've always thought of GET on /reports/ as returning all reports, but there are no hard and fast rules. Cheers! – Bharat Jan 01 '14 at 22:47
  • yes, '/reports/123' tell back end to locate a specific report (123). If it does not exist, backend should return '404 - not found'. If you want to get all report, you can add support of 'Get /reports' to return all reports under '/reports' url – Ming Chan Jan 02 '14 at 01:14