سؤال

I am not so experienced in client-server applications and I could not find exactly answer to my question anywhere in google.

I am developing part of application on server side and my collegue who develops frontend suggest me that I should manipulate his payload rather then act as a service.

I will explain it in example:

Frontent receives some data in tree structure (it is JSON message):

Node1
  NodeB
  NodeC
  NodeD
Node2
  NodeE
  NodeF
  NodeG

User wants to move NodeG from Node2 to Node1 (drag and drop).

So front-end application should send me whole payload and some instruction like "move NodeG to Node1" and wait until i process data, update database and send response with new structure and render it to the user?

or

front-end should send asynchronously just instructions to backend like "move NodeG to Node1" and care about displaying by itself.

as "Instruction" i mean some HTTP POST request.

هل كانت مفيدة؟

المحلول

A drag/drop UI typically encourages users to play around with the interface. You may not want to have every UI operation send data back to the server every time they interact with the interface. Depending on the specific interface it may not be an issue, but it's something to think about. What happens to the UI if the server response time starts to grow? How would users interact with the application if there were concurrency issues (a record is locked, etc) or permission issues?

One possibility is to have a staging-area in the front-end. For example, let the users drag and drop and manipulate the tree as much as they want, and then submit one request when they're finished to send the result to the server. You reduce calls this way, and protect against a lot of potential issues. As far as the server sees, there's just one POST, and probably a subsequent GET so the client can rerender the tree. If every UI interaction caused a POST, you would need to follow each one with a GET and a rerender to keep front and back ends in sync - probably not ideal because it doesn't scale well and eats up more resources than needed.

نصائح أخرى

If you value consistency then the service that stores the data should be the definitive 'master' source of what the data looks like. This means that the front end must defer to whatever the service says. Now that doesn't mean it cannot cache results, but it should not make assumptions about logic that may (or may not) be processed on the service.

eg. Lets assume the user moves NodeG from node2 to Node1. The front end can assume success and redisplay the tree, but what if the user does not have permission to perform this move? Or if NodeG has some other characteristic that prevents it from being moved? When happens if the user then attempts to move NodeG from node1 (as it appears) to Node3? Suddenly you're in a world of broken user interface, inconsistent data, unhappy users and a real nightmare to fix.

So, send the data to the service (whether full payload or just relevant changes is up to you), and let the service respond to the front end that then displays the changes. The front end can cache this tree structure for re-display purposes without asking for it again, but it must honour all changes that the service sends to it and must never attempt to persist the tree for itself.

One popular current 'state of the art' is to use a RESTful API service on the backend, and the front-end is responsible for data display and sending requests/commands to the server. This is usually done through simple HTTP requests to URLs with special meaning, but many other variants work generally the same way (with some varying details - think SOAP, etc).

In your case, the front-end loads up and calls a GET to /nodes, which returns a JSON from your back-end to your front-end with the full node structure as you outlined.

The user wants to move a node, so the front-end might POST to /nodes/move/{nodeToMove}/{nodeDestination}. The back-end attempts to execute the command, and then returns...well, what does the front-end want it to return? You can just return success/failure, or you can return the whole new structure. This depends on your particular situation - and if you don't need to return the whole new structure or the structure is very large, then don't return it.

How the front-end displays this is...well, up to the front-end person and will depend on use case, and there is no universal answer - it's about maximizing human usability. The front-end can "assume success", but then will have to figure out how to gracefully deal with the issue when an error returns or if data gets out of sync. What if the user request to move Node G under Node 1, then delete Node 2 and everything underneath it. If the first command failed, the second command might delete something unintentionally!

Then the question is of when to lock the UI - and the answer varies based on your use case and other aspects of what your program is actually doing. When a command that changes data has been issued it's usually best to block further changes until that first command has been verified to be completed, or you get into some weird situations - like trying to edit a file that has been deleted or that is currently being copied (will the copy show these edit changes?), etc.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى softwareengineering.stackexchange
scroll top