0

I am aware of a well-known question here: PUT vs POST in REST

However I am a bit confused in one of my case and would want to seek for advise to properly design my RESTful WS:

Assume my system work like this:

My system will have multiple batch jobs defined (e.g. JOB1, JOB2).

For every day, I will ask my system to create a list of batch job schedule, by providing a specific date (e.g. I passed in 2014-12-25, then system will create JOB1(2014-12-25) and JOB2(2014-12-25).

User can trigger a batch job schedule to execute.

I want to seek for advise to proper expose these as resource:

Should I do a POST or PUT to the resource /batchSchedules to trigger the creation of batchSchedules for a specific date? How should the URL looks like to make it a proper RESTful API?

What should the "schedule triggering" looks like?

I am thinking of these two choices, but both doesn't sounds quite right to me:


Approach 1:

To create schedule for a specific date: PUT to /batchSchedules/2014-12-25 with empty request body, as it seems that I am creating "bunch of schedules" as the resources declared in URL. (However, it does seems right because I am not going to replace it if I call it again, which doesn't looks quite well)

To trigger a schedule execute: PUT to /batchSchedules/2014-12-25/JOB1 as it seems replacing the batch schedule resources (but it looks strange coz I am not really replacing the resource, cannot take a POST here because I am actually not generating a child resources below the URL)

To get the status of a schedule with meaningful input: GET /batchSchedules/2014-12-25/JOB1

To get the status of a schedule: GET /batchSchedules?id=12345 which 12345 is the ID for a schedule


Approach 2: To create schedule for a specific date: POST to /batchSchedules with date in request body, as it seems that I am creating a child resource of batch schedules

To trigger a schedule execute: PUT to /batchSchedules/2014-12-25/JOB1 as it seems replacing the batch schedule resources (but it looks strange coz I am not really replacing the resource, cannot take a POST here because I am actually not generating a child resources below the URL)

To get the status of a schedule with meaningful input: GET /batchSchedules/2014-12-25/JOB1

To get the status of a schedule: GET /batchSchedules?id=12345 which 12345 is the ID for a schedule


Approach 3:

To get the status of a schedule with meaningful input: GET /batchSchedules?job=JOB1&date=2014-12-25

To get the status of a schedule: GET /batchSchedules/12345 which 12345 is the ID for a schedule

To create schedule for a specific date: POST to /batchSchedules with date in request body, as it seems that I am creating a bunch of child resources of batch schedules under /batchSchedules (doesn't seems quite good)

To trigger a schedule execute: PUT or POST to /batchSchedules?job=JOB1&date=2014-12-25 as it seems replacing the batch schedule resources (looks really strange to me)


Which of them is the appropriate way of exposing my WS in proper REST manner?

Community
  • 1
  • 1
Adrian Shum
  • 38,812
  • 10
  • 83
  • 131

1 Answers1

0

If I'm reading your question right, the client isn't providing any information besides the date to construct the schedule. If that's true, I'm going to argue you should be using a GET, and not a PUT or a POST. Conceptually, there's no reason here for a client to do anything to create a resource - it's all on the server side. All the client knows is "I want the batch job schedule for day X". Whether the server needs to create a new schedule or retrieve an existing schedule isn't something the client should need to care about.

GET /batchSchedules?date=2014-12-25
{
    "id": 12345,
    "self": "/batchSchedules/12345",
    "jobs": [{
            "id": 67890,
            ...
        },
        ...
    ]
}

POST /scheduledExecutions
{
    "scheduleId": 12345,
    "date": "2014-12-25"
}

The response from the post would either be a 200 OK if the batch is done immediately, or more likely a 202 Accepted, along with a Location request header for the URI for batch results, something like /scheduledExecutions/67890. Calling a GET on that URI would return status information on the batch, possibly including URIs to the statuses of various jobs in the batch.

GET /scheduledExecutions/67890
{
    "status": "In progress",
    "date": "2014-12-25",
    "jobs": [{
        "id": 13579,
        "status": "Complete",
        "self": "/scheduledJobs/13579"
    },
    {
        "id": 24680,
        "status": "In progress",
        "self": "/scheduledJobs/24680"
    }
}

If I misunderstood, and you're executing jobs, not whole schedules, then you'd have POST /scheduledJobs and GET /scheduledJobs instead of /scheduledExecutions.

Eric Stein
  • 13,209
  • 3
  • 37
  • 52
  • Thanks for the reply, I will try to further read into it. Just one thing: I want to avoid using GET in creating those "schedule", because I want the creation to be explicit, and GET /schedules/DATE should give me schedules (that is previous created) of a specific date. If that's my design decision, how should I expose it in a RESTful way? And I believe my idea of job schedule is more like your "schedule execution": my "schedule" is a job scheduled to execute for a specific date. – Adrian Shum Apr 01 '14 at 03:37
  • Well, if you're determined to use PUT/POST, it comes down to the information the client has. If the client can *fully* specify the schedule, then PUT is appropriate. If there's any information that can change which the client doesn't have, you *must* use POST. – Eric Stein Apr 01 '14 at 11:52