How to model an action in REST?

2019-06-27 23:09发布

Suppose I have Task and TimePeriod. TimePeriod represents the time I have worked on the task using start_time and end_time fields.

I would like for Task to support Starting/Stopping the task. Start will create a new TimePeriod with the current time. Stop will add end_time to the last TimePeriod.

I was thinking the REST URL will be like this: PUT /tasks/1011?do=start PUT /tasks/1011?do=stop

or maybe PUT /tasks/1011/start PUT /tasks/1011/stop

What is the proper way to make this REST style?

3条回答
爷、活的狠高调
2楼-- · 2019-06-27 23:16

Here is one alternative. Retrieve the task like this,

GET /task/1011

Then to start the task, POST it like this,

POST /ActiveTasks  

and to end the task,

POST /InactiveTasks   

In reality it doesn't matter what the URIs look like if you use the following representation for a task resource:

<Task>
  <Description>Do some stuff</Description>
  <Status>Active</Status>
  <Link rel="end" Method="POST" href="/InactiveTasks"/>
</Task>

or

<Task>
  <Description>Do some stuff</Description>
  <Status>InActive</Status>
  <Link rel="start" Method="POST" href="/ActiveTasks"/>
</Task>

Note that only one of the links will be available at any one time, depending on whether the task is currently active

查看更多
smile是对你的礼貌
3楼-- · 2019-06-27 23:19

You want to conform to HTTP method definitions as much as possible when using REST to take advantage of the uniform interface. Using this rule, you wouldn't want to use PUT or a query string to pass an action. PUT wouldn't fit because it is to be used to replace a resource.

POST would be the method you'd want to use. POST /tasks/1011/start with preferably a response code 303 to redirect them to a status page (if that's needed for your use cases) or code 400 if starting failed. Similar for stopping a task.

I highly recommend RESTful Web Services Cookbook as I'm using that as a guide to this answer and it covers other common REST questions.

查看更多
啃猪蹄的小仙女
4楼-- · 2019-06-27 23:33

I think Paul is real close, but it's important to note that pure REST requires an object/noun as a resource. Bearing in mind that I'm not a REST purest, I'm just throwing in my $0.02 as this pertains directly to REST. This is probably more technically correct:

Request: 
  POST /tasks/1011/timeperiod
Response: 201 Created response status with a Location header that points to 
  GET /tasks/1011/timeperiod/(identifier)

You should be able to then use /tasks/1011/timeperiod/(identifier) to update that. Stopping the time would probably involve a PUT, reseting (or rather deleting) the time would involve a DELETE. Your status page should come up anytime they actually land on GET /tasks/1011/timeperiod/(identifier).

Think key value pairs of object/id. Parameters in the GET shouldn't be necessary.

查看更多
登录 后发表回答