1

I am designing a timesheet app for logging user tasks using React for frontend and Django REST Framework for backend. The database is PostgreSQL and I have a table for recording the tasks with 4 columns: date, start_time, duration, description.

I need a way to support the updating of a task after the user had created several. The problem is that each task is dependent on all the previous tasks, since its start_time will change if the duration of a task before it changes. So for example, suppose that task 1 has a start_time of 13:00 and a duration of 1 hour, task 2 has a start_time of 14:00 and a duration of 1 hour, and so on. If the user decided to update the duration of task 1 from 1 hour to 2 hours, that means the start_time of task 2 and all subsequent tasks must be increased by 1 hour.

I'm wondering what is the best way to implement such cascading updates. First option is to make the API backend responsible for it, so whenever the React frontend sends out a PUT request for a task, the DRF backend will not only update that task but also all subsequent tasks as well. Second option is to offload everything to the React frontend, making it responsible for sending out multiple PUT requests, for the updated task as well as all subsequent tasks.

I would think the first option of letting the backend handles everything is a better design, since this problem is technically a form of database constraint. But not too sure if it is appropriate for a REST API to handle. What would be the best practice in this case?

4
  • Which way best meets your application's specific requirements for maintainability, performance, etc.? Commented Jun 7, 2021 at 23:37
  • Backend handling it should be more performant as it will save network requests. For maintainability, I guess they are about equal?
    – Alvin
    Commented Jun 7, 2021 at 23:57
  • 2
    Which is more likely to leave the database in an inconsistent state? Also, consider whether you really need to store start-time. You may, but if you don't then maybe this question is moot. Is it really start-time you need to store, or is it, lag-time or not-before-time which are facts from the user, and not dependent on prior tasks?
    – joshp
    Commented Jun 8, 2021 at 1:09
  • 2
    @joshp Leaving it to the frontend can potentially cause inconsistency, e.g. if the client crashed halfway through finishing a cascading update. In comparison, Django allows tying transactions to HTTP requests for ensuring atomicity.
    – Alvin
    Commented Jun 9, 2021 at 0:17

2 Answers 2

1

I would think the first option of letting the backend handles everything is a better design

Yes.

There are tradeoffs, of course.

The heuristic to use is to think about how we would do this on the web: is it OK to have the client submit one form, and in response the server modifies multiple web pages? Of course.

The semantics of the request message are specific to one resource (specifically, the resource identified by the target-uri), but it is perfectly normal that the implementation might modify many resources during the handling of that request.

What you do need to be aware of is caching; a general purpose client is not going to know that many resources are going to change, and may therefore end up using a stale copy of some other resource. In the language of the browser: the page you changed refreshes "automatically", but another web page may show the old data until you force the cache to invalidate its local copy of the old value.

It's not really all that different from what happens when somebody else edits a page on the server; you continue looking at your old copy until it is invalidated by the cache. Or the case where you fetch two similar pages, but a change happens between retrieving a copy of the first and retrieving a copy of the second.

0

One additional thing you need to consider is whether violations of constraints should be prevented by the web service or can be left to be handled by the client. In your example, a task sequence plan where a dependent task is started before the prerequisite task ends might be invalid but admissible as an intermediate state while editing the whole plan, so it might make sense to let the client sort it out.

However, consider a customer buying something from a web shop using some credit he has at that shop. Should the client be allowed to post an order and then deduct the amount from his account in a second step?

That would certainly attract quite a number of new customers, not the kind you wish to have, though :-)

So in general, it is desirable that each single modifying REST action leaves the domain in a consistent state. If overlapping tasks are not allowed, don't rely on the client to ensure consistency.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.