Consider an automated build system that stores results in a database and offers tabular display of results via dynamic html in response to http GET requests. Lots of different users want to see different subsets of the results, so there are parsing scripts in PHP each of which accepts multiple optional filtering parameters and values. For example, (I'm leaving off the http part so nobody here actually clicks this example URL):
display_results.php?componenent_name=my_comp1&build_type=build_type1&build_owner=fred
Even if the list of all possible parameters and their permitted values are listed on some help page, when the user is creating a request URL, s/he may not have that documentation at hand. Instead, depends on memorizing the valid parameters (including their spelling) and the allowed values. Sometimes s/he will get that wrong.
Question
From the point of view of end-user usability as well as developer maintainability, which of the following options is best in response to such user errors:
For example, if the database contains data for build_type1 and fred and joe for three components called comp1, comp2, and comp3, and user (erroneously) writes:
display_results.php?name=comp1,comp2&build_type=build_type1&build_owner=john
I'm defining usability as consistency with widely-used, well-behaved web apps that are out there -- if users are happy with those they would be happy with the app I'm describing too.
I am asking this question because I am a key user of such scripts, make a good number of enhancement requests, and want to get some backing for further requests.
=== About the interface -- free-form or "builder page". Yes, I am talking about free-form. There is a "builder page" in the system but (a) it never offers all the options that all users seem to want and (b) I have not been able to push through a "create permalink" enhancement request.
=== Thanks for chosen answer -- not enough space in comment:
Thanks @pygorex1! You gave an answer that puts my question in the context of a well-known software construct -- the API. And gave a good (if perhaps exaggerated ;-) ) example of the impact of violating these principles. Finally, something had been bothering me about these scripts' APIs, and when you mentioned "self-documenting", you connected it up for me. What was bothering me was that when there's little documentation (because it's costly to keep up to date) and with partial results returned on user error (mine!), I don't learn anything about the system. "Self-documenting" is probably the most succinct justification for the error-handling design you've recommended. Easier sell to users and maintainers!
This sounds remarkably like an API. One of the hallmarks of a good API is a having a clear and consistent syntax so users can get predictable results. Violating the syntax should result in a error.
Returning partial results even though the syntax is incorrect is a terrible design: when a user isn't clearly stating what data they want there's a good chance the data returned won't be useful or will be discarded. Even worse, the data may be treated as being in a valid context even when it's not.
An example. The system is designed to ignore invalid parameters. A client sends a comoponent_name
parameter (a misspelling of component_name
) requesting all components of type 'A'. Subsequently, the system returns components of all types ('A', 'B', 'C' ... 'Z'). The client treats these results as all being of type 'A' and bases internal calculations and business logic on these results. Chaos ensues, as management bases their business decisions largely on this internal data analysis, the client jumps head-first into the wrong market segment and goes bankrupt.
Now, this is a doomsday scenario, but it illustrates a point: you can mitigate and even prevent systemic bugs by clearly defining your inputs and outputs.
Before returning any data, verify input parameters. When an invalid parameter is encountered return an error message explaining the correct syntax. This way, the system is self-documenting and will return predictable results.
If it were me, I'd display as much valid info as possible, list the invalid parameters in an error message, and then provide a list of valid parameters that weren't included in the 'valid info' section. Perhaps a form for each valid parameter with an associated input field. Then perhaps AJAX in the new valid info as it changes.
My first instinct would be to have a builder page for the URL instead of allowing users to muddle around. Unless there is either a reason you can't have a builder page, this is my suggestion. This way, you don't have to deal with the issue of informing the users to changes. You will also have the option to only present valid options in some cases.
Depending on the desired behavior of the app in deployment, I would suggest either bouncing to a 400 Bad Request or displaying a result set using only the data provided with some kind of flag displaying notifying the user that certain limiting parameters have been omitted.
You have to evaluate the specificity of the data being return, as well as whether or not it is imperative that a dataset always be return in lieu of an error. If this is an application merely gathering data for user consumption, such as a search for a catalog, then it is certainly acceptable to use the parameters provided and merely limit off those.
Airing on the side of security however, many large web applications (Amazon for example) will ensure that all parameters are included to force the user to utilize UI components within the site rather than muddling with the url (as those doing the muddling generally don't have the best intents.) Some examples can be seen on Amazon while browsing if you eliminate the node parameter or the ie parameter (this determines the charset for display.) Bouncing requests with omitted or fudged parameters can be a good way to maintain control of unwanted input.