2

I am starting a new project and I was trying to figure out if I should follow a RESTful approach or not. By reading different sources on the internet I am getting more and more confused on how a truly RESTful approach should be. Some people say that the REST request (ie, both the URI and the rest of the content of the HTTP request) should never describe an action with something other than the HTTP verbs. Some others say that since the HTTP verbs are limited, the HTTP request body can provide additional info regarding which action need to be applied on the data described by the URI. Which of the two is correct? I will give you a simplified description of the software I am trying to build and how I think it should implemented with REST: The user must be able to upload/delete/edit data on the server. Then, he must be able to perform 10 different kinds of analysis (analysis01-analysis10) on the server in the form of jobs. So, the user will be submitting jobs to the server. When the jobs are finished the user will be able to get the results of the analysis. So here is how I think is the right way of implementing this in REST:

Datasets:

POST /datasets/     - To create/upload a new dataset
GET /datasets/      - To get a list of all the available datasets.
GET /datasets/01    - To get info about dataset 01
DELETE /datasets/01 - To delete dataset 01

Jobs:

POST /analysis01_jobs/     - Submit a new job for analysis01
GET /analysis01_jobs/      - Get a list with all the submitted analysis01 jobs
GET /analysis10_jobs/      - Get a list with all the submitted analysis10 jobs
GET /analysis01_jobs/01    - Get the status of job '01' which performs analysis of type 01
DELETE /analysis10_jobs/01 - Delete/Cancel job '01' which performs analysis of type 10

As you can see each type of analysis has a different REST URL path for the jobs. I was thinking to change this and put all jobs under the same path: "/analysis_jobs/" and specify the type of analysis I want inside the HTTP header. But this will imply the type of action I want the server to perform. Thus this this is not RESTful any more. Right or wrong?

When a job is complete it will produce a "result" resource. So the REST API for this will be something like this:

- There is no POST here because only the job that runs on the server can generate results.
GET /analysis01_results/      - To get a list of all the available results from analysis01 jobs
GET /analysis01_results/01    - To get the results of a job that performed analysis of type 01. The body of the HTTP response will also contain info about the "parent" job and data.
DELETE /analysis01_results/01 - To delete the above results.

Is the above design RESTful?

Thank you in advance!

AstrOne
  • 3,569
  • 7
  • 32
  • 54
  • This looks OK. What is the body you `POST` when creating a new job? Maybe the type can be part of this resource represenation. –  Mar 03 '15 at 10:09
  • To be honest I am not quite sure how I will do that yet. It will be either jason or XML (which will include nested elements) and it will include job configuration settings. Do you think it will be OK if I include the type of the analysis in the XML/Jason? Isn't this going to break the "RESTfulness" since the type implies an action/verb? Thanks. – AstrOne Mar 03 '15 at 11:13

2 Answers2

1

REST is about machine to machine communication. If you don't have at least 2 different clients I don't think it will worth the effort to implement a REST service.

Some people say that the REST request (ie, both the URI and the rest of the content of the HTTP request) should never describe an action with something other than the HTTP verbs. Some others say that since the HTTP verbs are limited, the HTTP request body can provide additional info regarding which action need to be applied on the data described by the URI. Which of the two is correct?

You should read the Fielding dissertation, it is the only true source of knowledge. :D

Both can be wrong. The second one is closer to the truth. If you need to describe a new action, you can always define a new resource and use it with the existing HTTP verbs. For example ANALYZE /datasets/1 can be described with POST /analysis/ {dataset: {id: 1}}.

Be aware that we are talking here about hyperlinks:

POST /datasets/ - To create/upload a new dataset

This is an action, but this is a hyperlink as well in the representation of the /datasets/, which you can access with GET /datasets/. What you can add to the body is the To create/upload a new dataset part, so the client won't need to know anything about the URI structure to understand what the link does.

{
    href: "/datasets/",
    method: "POST", 
    rel: "/docs/datasets/create"
}

You can access the form description with GET /docs/datasets/create. (Currently ppl are working on a standard format, to describe these descriptions, e.g. RDF + Hydra. But that is not production ready currently.)

Ofc. you can expand the description if you want:

{
    href: "/datasets/",
    method: "POST", 
    rel: "/docs/datasets/create",
    label: "Create a new dataset",
    description: "You can create a new dataset by sending this form.",
    fields: {
        label: {
            type: "string", 
            label: "Title", 
            description: "You can give a title to the dataset here.",
            ...
        },
        records: {
            type: "array", 
            ...
        }
    }
}

but it is easier to generate a documentation if you describe everything in a docs file, probably in JSON-LD for the REST clients and in HTML for the 3rd party developers of the clients.

POST /analysis01_jobs/ - Submit a new job for analysis01

GET /analysis01_results/ - To get a list of all the available results from analysis01 jobs

GET /analysis01_results/01 - To get the results of a job that performed analysis of type 01. The body of the HTTP response will also contain info about the "parent" job and data.

I would rather use

  • POST /jobs/ {analysis: {id: "01"}}
  • GET /analysis/01/jobs
  • GET /jobs/2345/result
Community
  • 1
  • 1
inf3rno
  • 24,976
  • 11
  • 115
  • 197
  • Thanks! Pretty good explanation but one thing kinda confused me. What is this "rel"? If it an actual address were someone can find a web page to create/add data? or is it a REST URL? I assume the first because "create" is a verb, so it can't be a REST URL, right? – AstrOne Mar 04 '15 at 11:25
  • Just to clarify: Will the page to create/add data that I am referring to in the above comment eventually lead to a REST request? i.e., POST /datasets/ – AstrOne Mar 04 '15 at 11:36
  • 1
    @AstrOne The `/docs/datasets/create` can be a page which describes the dataset creation action the same way you can see it in the expanded version. You can create a single docs file if you want to: `/docs#datasets.create` or you can use just the expanded version without visiting the given page. It depends on your choice. You can use json-ld or other rdf formats to describe the documentation, or your custom json format if you want. I recommend using existing formats so your code will be easier to reuse later. – inf3rno Mar 04 '15 at 16:10
0

You are going in the right direction but still you can moderate it.

1-

Is REST a good solution for my application?

Yes and you can compare it .REST vs SOAP on this question

2-

Use PUT for Creating or Adding a resource or Job instead of POST.

Resources are manipulated using a fixed set of four create, read, update, delete operations: PUT, GET, POST, and DELETE. PUT creates a new resource, which can be then deleted by using DELETE. GET retrieves the current state of a resource in some representation. POST transfers a new state onto a resource. See Responding to HTTP Methods and Requests for more information. Source Oracle docs

Community
  • 1
  • 1
smali
  • 4,687
  • 7
  • 38
  • 60